[PATCH] Run postinstall scripts in a thread with progress bars - take 3
Igor Pechtchanski
pechtcha@cs.nyu.edu
Mon Mar 24 22:48:00 GMT 2003
On 21 Mar 2003, Robert Collins wrote:
> On Fri, 2003-03-21 at 08:49, Igor Pechtchanski wrote:
> > On 21 Mar 2003, Robert Collins wrote:
> >
> > > On Fri, 2003-03-21 at 04:49, Igor Pechtchanski wrote:
> > >
> > > > Same as above, but regenerated against HEAD. ChangeLog is the same.
> > > > The only thing about this patch that really makes me uncomfortable is
> > > > having to run through iterators/FindVisitors twice. Any suggestions for
> > > > improvement are welcome.
> > >
> > > Sight unseen - instead of counting in the visitor and iterators, push
> > > all the script details (and package references if appropriate) onto a
> > > list or vector first time through.
> > >
> > > Then, simply walk the list.
> > > Rob
>
> I've give a fuller review later. However:
>
> This code can be simplified:
> 1) iterate over the dependency ordered packages and push all their
> scripts into the 'to be run' collection. Save the current count of
> scripts.
> 2) iterate over the files in the directory.
> 3) subtract the count in 1) from the now total to get the total scripts
> to be run.
> 3a) optional: iterate forward through the scripts vector and remove any
> duplicates. There may even be an stl order preserving call to do this
> (removing the duplicates from pos->end()).
> 4) iterate through the scripts and run them.
>
> 3a) is optional because we don't error on missing scripts IIRC.
Rob,
I wanted (and still want) to keep the two bar progress on this. The
second bar would show progress through packages, and the first - progress
through the scripts *in the current package*.
> Alteratively/also you could extract the script running and screen
> updating code to a new method.
> Rob
Done. I've also done some restructuring of the Script class and enabled
the "#if 0"'d code from the previous patch, now that the progress bars
exist.
I've attached the next iteration. Should apply cleanly to HEAD.
Igor
==============================================================================
ChangeLog:
2003-03-24 Igor Pechtchanski <pechtcha@cs.nyu.edu>
* threebar.h (WM_APP_START_POSTINSTALL): New message.
(WM_APP_POSTINSTALL_THREAD_COMPLETE): New message.
* threebar.cc (ThreeBarProgressPage::OnMessageApp):
Add handling for WM_APP_START_POSTINSTALL and
WM_APP_POSTINSTALL_THREAD_COMPLETE.
* install.cc (do_install_thread): Set next_dialog to
IDD_S_POSTINSTALL.
* desktop.cc (DesktopSetupPage::OnFinish): Move the
do_postinstall call to ThreeBarProgressPage::OnMessageApp.
* script.h (Script::fullName): New member function.
(Script::run): New member function.
* script.cc (Script::fullName): Implement.
(Script::run): Implement.
(run): Enable "#if 0"'d code.
* postinstall.cc (Progress): New extern variable.
(RunFindVisitor::visitFile): Add script to vector
instead of running.
(RunFindVisitor::_scripts): New member variable.
(run_package_scripts): New static function.
(do_postinstall_thread): Rename do_postinstall to. Add
Progress bar and text setting. Add package count.
(do_postinstall_reflector): New static function.
(do_postinstall): Rename to do_postinstall_thread.
Create a thread instead.
--
http://cs.nyu.edu/~pechtcha/
|\ _,,,---,,_ pechtcha@cs.nyu.edu
ZZZzz /,`.-'`' -. ;-;;,_ igor@watson.ibm.com
|,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski
'---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow!
Oh, boy, virtual memory! Now I'm gonna make myself a really *big* RAMdisk!
-- /usr/games/fortune
-------------- next part --------------
Index: desktop.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/desktop.cc,v
retrieving revision 2.34
diff -u -p -r2.34 desktop.cc
--- desktop.cc 25 Nov 2002 22:12:08 -0000 2.34
+++ desktop.cc 24 Mar 2003 22:04:08 -0000
@@ -397,8 +397,6 @@ DesktopSetupPage::OnFinish ()
HWND h = GetHWND ();
save_dialog (h);
do_desktop_setup ();
- NEXT (IDD_S_POSTINSTALL);
- do_postinstall (GetInstance (), h);
return true;
}
Index: install.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/install.cc,v
retrieving revision 2.60
diff -u -p -r2.60 install.cc
--- install.cc 17 Mar 2003 22:23:33 -0000 2.60
+++ install.cc 24 Mar 2003 22:04:08 -0000
@@ -455,7 +455,7 @@ do_install_thread (HINSTANCE h, HWND own
num_installs = 0, num_uninstalls = 0, num_replacements = 0;
rebootneeded = false;
- next_dialog = IDD_DESKTOP;
+ next_dialog = IDD_S_POSTINSTALL;
io_stream::mkpath_p (PATH_TO_DIR, String ("file://") + get_root_dir ());
Index: postinstall.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/postinstall.cc,v
retrieving revision 2.12
diff -u -p -r2.12 postinstall.cc
--- postinstall.cc 20 Mar 2003 10:02:51 -0000 2.12
+++ postinstall.cc 24 Mar 2003 22:04:08 -0000
@@ -29,40 +29,113 @@ static const char *cvsid =
#include "FilterVisitor.h"
#include "package_db.h"
#include "package_meta.h"
+#include "resource.h"
+#include "threebar.h"
+
+extern ThreeBarProgressPage Progress;
class RunFindVisitor : public FindVisitor
{
public:
- RunFindVisitor (){}
+ RunFindVisitor (std::vector<Script> *scripts) : _scripts(scripts) {}
virtual void visitFile(String const &basePath, const WIN32_FIND_DATA *theFile)
{
- run_script ("/etc/postinstall/", theFile->cFileName, TRUE);
+ String fn = String("/etc/postinstall/")+theFile->cFileName;
+ _scripts->push_back(Script (fn));
}
virtual ~ RunFindVisitor () {}
protected:
RunFindVisitor (RunFindVisitor const &);
RunFindVisitor & operator= (RunFindVisitor const &);
+private:
+ std::vector<Script> *_scripts;
};
-
-void
-do_postinstall (HINSTANCE h, HWND owner)
+
+static void
+run_package_scripts (String const &packagename, std::vector<Script> &scripts)
{
- next_dialog = 0;
+ Progress.SetText2 (packagename.cstr_oneuse());
+ int numscr = scripts.size();
+ int s = 0;
+ Progress.SetBar1 (s, numscr);
+ for (std::vector<Script>::iterator script = scripts.begin();
+ script != scripts.end();
+ ++script)
+ {
+ Progress.SetText3 (script->fullName().cstr_oneuse());
+ script->run(TRUE);
+ ++s;
+ Progress.SetBar1 (s, numscr);
+ }
+ Progress.SetText3 ("");
+}
+
+static void
+do_postinstall_thread (HINSTANCE h, HWND owner)
+{
+ next_dialog = IDD_DESKTOP;
+
+ Progress.SetText1 ("Running...");
+ Progress.SetText2 ("");
+ Progress.SetText3 ("");
+ Progress.SetBar1 (0, 1);
+ Progress.SetBar2 (0, 1);
+
init_run_script ();
SetCurrentDirectory (get_root_dir ().cstr_oneuse());
packagedb db;
+ std::vector<packagemeta*> packages;
PackageDBConnectedIterator i = db.connectedBegin ();
while (i != db.connectedEnd ())
{
packagemeta & pkg = **i;
if (pkg.installed)
- for (std::vector<Script>::iterator script=pkg.installed.scripts().begin(); script != pkg.installed.scripts().end(); ++script)
- run_script ("/etc/postinstall/", script->baseName(), TRUE);
+ packages.push_back(&pkg);
++i;
}
- RunFindVisitor myVisitor;
+ int numpkg = packages.size() + 1;
+ int k = 0;
+ for (i = packages.begin (); i != packages.end (); ++i)
+ {
+ packagemeta & pkg = **i;
+ run_package_scripts(pkg.name, pkg.installed.scripts());
+ ++k;
+ Progress.SetBar2 (k, numpkg);
+ }
ExcludeNameFilter notDone("*.done");
- FilterVisitor excludeDoneVisitor(&myVisitor, ¬Done);
String postinst = cygpath ("/etc/postinstall");
+ std::vector<Script> scripts;
+ RunFindVisitor myVisitor (&scripts);
+ FilterVisitor excludeDoneVisitor(&myVisitor, ¬Done);
+ Progress.SetBar1 (0, 1);
Find (postinst).accept (excludeDoneVisitor);
+ run_package_scripts("No package", scripts);
+ Progress.SetBar2 (numpkg, numpkg);
+}
+
+static DWORD WINAPI
+do_postinstall_reflector (void *p)
+{
+ HANDLE *context;
+ context = (HANDLE *) p;
+
+ do_postinstall_thread ((HINSTANCE) context[0], (HWND) context[1]);
+
+ // Tell the progress page that we're done running scripts
+ Progress.PostMessage (WM_APP_POSTINSTALL_THREAD_COMPLETE);
+
+ ExitThread(0);
}
+
+static HANDLE context[2];
+
+void
+do_postinstall (HINSTANCE h, HWND owner)
+{
+ context[0] = h;
+ context[1] = owner;
+
+ DWORD threadID;
+ CreateThread (NULL, 0, do_postinstall_reflector, context, 0, &threadID);
+}
+
Index: script.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/script.cc,v
retrieving revision 2.7
diff -u -p -r2.7 script.cc
--- script.cc 20 Mar 2003 10:02:51 -0000 2.7
+++ script.cc 24 Mar 2003 22:04:08 -0000
@@ -182,13 +182,8 @@ run (const char *sh, const char *args, c
si.hStdOutput = file_out.handle ();
si.hStdError = file_out.handle ();
si.dwFlags |= STARTF_USESHOWWINDOW;
-#if 0
si.wShowWindow = SW_HIDE;
- flags = CREATE_NO_WINDOW; // Note: might not work on Win9x
-#else
- // TODO: introduce a script progress tracker and use the above
- si.wShowWindow = SW_MINIMIZE;
-#endif
+ flags = CREATE_NO_WINDOW; // Note: this is ignored on Win9x
}
BOOL createSucceeded = CreateProcess (0, cmdline, 0, 0, inheritHandles,
@@ -250,11 +245,14 @@ try_run_script (String const &dir, Strin
run_script (dir.cstr_oneuse(), (fname + ".bat").cstr_oneuse());
}
+static const char etc_postinstall[] = "/etc/postinstall/";
+
bool
Script::isAScript (String const &file)
{
/* file may be /etc/postinstall or etc/postinstall */
- if (file.casecompare ("/etc/postinstall/", 17) && file.casecompare ("etc/postinstall/", 16))
+ if (file.casecompare (etc_postinstall, sizeof(etc_postinstall)) &&
+ file.casecompare (etc_postinstall+1, sizeof(etc_postinstall)-1))
return false;
if (file.cstr_oneuse()[file.size() - 1] == '/')
return false;
@@ -267,10 +265,23 @@ Script::Script (String const &fileName)
}
String
-Script::baseName()const
+Script::baseName() const
{
String result = scriptName;
while (result.find ('/'))
result = result.substr(result.find ('/'));
return result;
}
+
+String
+Script::fullName() const
+{
+ return scriptName;
+}
+
+void
+Script::run(BOOL to_log) const
+{
+ run_script("", scriptName, to_log);
+}
+
Index: script.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/script.h,v
retrieving revision 2.4
diff -u -p -r2.4 script.h
--- script.h 20 Mar 2003 10:02:51 -0000 2.4
+++ script.h 24 Mar 2003 22:04:08 -0000
@@ -33,7 +33,9 @@ class Script {
public:
static bool isAScript (String const &file);
Script (String const &fileName);
- String baseName()const;
+ String baseName() const;
+ String fullName() const;
+ void run(BOOL to_log = FALSE) const;
private:
String scriptName;
};
Index: threebar.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/threebar.cc,v
retrieving revision 2.4
diff -u -p -r2.4 threebar.cc
--- threebar.cc 26 Jun 2002 21:35:16 -0000 2.4
+++ threebar.cc 24 Mar 2003 22:04:08 -0000
@@ -172,6 +172,18 @@ bool
}
case WM_APP_INSTALL_THREAD_COMPLETE:
{
+ // Install is complete and we want to go on to the postinstall.
+ Window::PostMessage (WM_APP_START_POSTINSTALL);
+ break;
+ }
+ case WM_APP_START_POSTINSTALL:
+ {
+ // Start the postinstall script thread.
+ do_postinstall (GetInstance (), GetHWND ());
+ break;
+ }
+ case WM_APP_POSTINSTALL_THREAD_COMPLETE:
+ {
// Re-enable and "Push" the Next button
GetOwner ()->SetButtons (PSWIZB_NEXT);
GetOwner ()->PressButton (PSBTN_NEXT);
Index: threebar.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/threebar.h,v
retrieving revision 2.4
diff -u -p -r2.4 threebar.h
--- threebar.h 21 Sep 2002 09:36:46 -0000 2.4
+++ threebar.h 24 Mar 2003 22:04:08 -0000
@@ -32,6 +32,8 @@
#define WM_APP_START_SETUP_INI_DOWNLOAD WM_APP+6
#define WM_APP_SETUP_INI_DOWNLOAD_COMPLETE WM_APP+7
// desktop.h: WM_APP_UNATTENDED_FINISH WM_APP+8
+#define WM_APP_START_POSTINSTALL WM_APP+9
+#define WM_APP_POSTINSTALL_THREAD_COMPLETE WM_APP+10
class ThreeBarProgressPage:public PropertyPage
{
More information about the Cygwin-apps
mailing list