[PATCH] Run postinstall scripts in a thread with progress bars - take 3
Igor Pechtchanski
pechtcha@cs.nyu.edu
Tue Mar 25 01:33:00 GMT 2003
On Mon, 24 Mar 2003, Igor Pechtchanski wrote:
> On 25 Mar 2003, Robert Collins wrote:
>
> > On Tue, 2003-03-25 at 11:00, Igor Pechtchanski wrote:
> > > > run_package_scripts cries our for a helper class IMO.
> > > >
> > > > i.e. ScriptRunner with
> > > > a) constructor
> > > > b) destructor
> > > > c) run(std::vector<Script> const &) method.
> > > > d) operator () (Script const &aScript) method.
> > >
> > > I don't see the benefit of run(); it'll be subsumed by operator(), IMO.
> > > Otherwise, I'll give it a shot.
> >
> > well, you'll have one instance of ScriptRunner for both the dependency
> > order package scripts, and the found-by-filename scripts. If you have
> > pre-running-a-vector or post-running-a-vector code, then that belongs in
> > run(). If that code goes into the constructor, then sure, eliminate
> > run().
>
> Yep, I think the pre-post vector code could go into the
> constructor/destructor.
>
> > > > this:
> > > > for (std::vector<Script>::iterator script = scripts.begin();
> > > > + script != scripts.end();
> > > > + ++script)
> > > >
> > > > then becomes
> > > > *this = for_each (scripts.begin(), scripts.end(), *this);
> > >
> > > We could probably just lose the return value...
> >
> > Check the template, IIRC it takes a copy of the object, calls the copy's
> > operator (), then returns a copy of the copy.
> > i.e. if we want failure stats, script run counts etc, we need the return
> > value.
> > Rob
>
> Yes, but we don't keep failure stats. If we ever decide to, we can easily
> capture the return value later. I'm pretty sure we can ignore it for now.
>
> Thanks for the feedback. I'll send the next iteration soon.
> Igor
...and here it is. Attached.
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::ETCPostinstall): New static member constant.
* script.cc (Script::fullName): Implement.
(Script::run): Implement.
(Script::ETCPostinstall): Define.
(Script::isAScript): Use ETCPostinstall instead of a
hardcoded string constant.
(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.
(RunScript): New helper class for use in for_each.
(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 25 Mar 2003 01:24:28 -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 25 Mar 2003 01:24:28 -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 25 Mar 2003 01:24:28 -0000
@@ -29,40 +29,124 @@ static const char *cvsid =
#include "FilterVisitor.h"
#include "package_db.h"
#include "package_meta.h"
+#include "resource.h"
+#include "threebar.h"
+
+#include <algorithm>
+
+using namespace std;
+
+extern ThreeBarProgressPage Progress;
class RunFindVisitor : public FindVisitor
{
public:
- RunFindVisitor (){}
+ RunFindVisitor (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:
+ vector<Script> *_scripts;
};
-
-void
-do_postinstall (HINSTANCE h, HWND owner)
+
+class RunScript : public unary_function<Script const &, void>
{
- next_dialog = 0;
+public:
+ RunScript(String const &name, int num) : _num(num), _cnt(0)
+ {
+ Progress.SetText2 (name.cstr_oneuse());
+ Progress.SetBar1 (_cnt, _num);
+ }
+ virtual ~RunScript()
+ {
+ Progress.SetText3 ("");
+ }
+ void operator() (Script const &aScript)
+ {
+ Progress.SetText3 (aScript.fullName().cstr_oneuse());
+ aScript.run(TRUE);
+ ++_cnt;
+ Progress.SetBar1 (_cnt, _num);
+ }
+private:
+ int _num;
+ int _cnt;
+};
+
+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;
+ 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;
+ for_each (pkg.installed.scripts().begin(), pkg.installed.scripts().end(),
+ RunScript(pkg.name, pkg.installed.scripts().size()));
+ ++k;
+ Progress.SetBar2 (k, numpkg);
+ }
ExcludeNameFilter notDone("*.done");
- FilterVisitor excludeDoneVisitor(&myVisitor, ¬Done);
String postinst = cygpath ("/etc/postinstall");
+ vector<Script> scripts;
+ RunFindVisitor myVisitor (&scripts);
+ FilterVisitor excludeDoneVisitor(&myVisitor, ¬Done);
+ Progress.SetBar1 (0, 1);
Find (postinst).accept (excludeDoneVisitor);
+ for_each (scripts.begin(), scripts.end(),
+ RunScript("No package", scripts.size()));
+ 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 25 Mar 2003 01:24:28 -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());
}
+char const Script::ETCPostinstall[] = "/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 (ETCPostinstall, sizeof(ETCPostinstall)) &&
+ file.casecompare (ETCPostinstall+1, sizeof(ETCPostinstall)-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 25 Mar 2003 01:24:28 -0000
@@ -30,12 +30,15 @@ void init_run_script ();
void try_run_script (String const &dir, String const &fname);
class Script {
- public:
- static bool isAScript (String const &file);
- Script (String const &fileName);
- String baseName()const;
- private:
- String scriptName;
+public:
+ static bool isAScript (String const &file);
+ Script (String const &fileName);
+ String baseName() const;
+ String fullName() const;
+ void run(BOOL to_log = FALSE) const;
+private:
+ String scriptName;
+ static char const ETCPostinstall[];
};
#endif /* SCRIPT_H */
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 25 Mar 2003 01:24:28 -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 25 Mar 2003 01:24:29 -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