From 83c1ecb571ff13143d57ba190a603fbdf433431d Mon Sep 17 00:00:00 2001 From: "sgehani%netscape.com" Date: Wed, 5 Apr 2000 05:16:05 +0000 Subject: [PATCH] * Fixing ui/engine thread communication flakiness. * Expecting .xpis in a tucked away ./xpi/ dir now. * Renamed installer binary target to mozilla-installer. Not part of build just yet. b = 16300 --- xpinstall/wizard/unix/src2/Makefile.in | 2 +- xpinstall/wizard/unix/src2/XIDefines.h | 4 +- xpinstall/wizard/unix/src2/XIErrors.h | 3 +- xpinstall/wizard/unix/src2/nsInstallDlg.cpp | 74 +++++++++--- xpinstall/wizard/unix/src2/nsInstallDlg.h | 1 + xpinstall/wizard/unix/src2/nsXIContext.cpp | 2 + xpinstall/wizard/unix/src2/nsXIContext.h | 11 ++ xpinstall/wizard/unix/src2/nsXIEngine.cpp | 125 +++++++++++++++----- xpinstall/wizard/unix/src2/nsXIEngine.h | 6 +- 9 files changed, 181 insertions(+), 47 deletions(-) diff --git a/xpinstall/wizard/unix/src2/Makefile.in b/xpinstall/wizard/unix/src2/Makefile.in index 7c97b8102df..f2e11675dc1 100644 --- a/xpinstall/wizard/unix/src2/Makefile.in +++ b/xpinstall/wizard/unix/src2/Makefile.in @@ -28,7 +28,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -PROGRAM = MozInstaller +PROGRAM = mozilla-installer CPPSRCS = \ nsXInstallerDlg.cpp \ diff --git a/xpinstall/wizard/unix/src2/XIDefines.h b/xpinstall/wizard/unix/src2/XIDefines.h index 5524c6c83e8..74af3c82d7b 100644 --- a/xpinstall/wizard/unix/src2/XIDefines.h +++ b/xpinstall/wizard/unix/src2/XIDefines.h @@ -42,6 +42,7 @@ #define SELECT_DIR "Select a directory" #define DESCRIPTION "Description" #define DOWNLOADING "Downloading..." +#define PREPARING "Preparing installer modules..." #define EXTRACTING "Extracting installer files..." #define INSTALLING "Installing" @@ -105,8 +106,9 @@ /*--------------------------------------------------------------------* * Macros *--------------------------------------------------------------------*/ -#define TMP_DIR_TEMPLATE "./.tmp.xi.%d" +#define TMP_DIR_TEMPLATE "%s/.tmp.xi.%d" // /.tmp.xi. #define TMP_EXTRACT_SUBDIR "bin" +#define XPI_DIR "./xpi" #define XPISTUB "libxpistub.so" #define FN_INIT "XPI_Init" diff --git a/xpinstall/wizard/unix/src2/XIErrors.h b/xpinstall/wizard/unix/src2/XIErrors.h index 8740aca054e..dee6a78ed46 100644 --- a/xpinstall/wizard/unix/src2/XIErrors.h +++ b/xpinstall/wizard/unix/src2/XIErrors.h @@ -53,7 +53,8 @@ E_LIB_OPEN = -418, /* couldn't open stub lib */ E_LIB_SYM = -419, /* couldn't get symbol in lib */ E_XPI_FAIL = -420, /* a xpistub call failed */ - E_INSTALL = -421 /* a .xpi failed to install */ + E_INSTALL = -421, /* a .xpi failed to install */ + E_CP_FAIL = -622 /* copy of a xpi failed */ }; #define FATAL_ERR_THRESHOLD -500 /* errs below this cause app quit */ diff --git a/xpinstall/wizard/unix/src2/nsInstallDlg.cpp b/xpinstall/wizard/unix/src2/nsInstallDlg.cpp index 3b197309e7d..1eb188e7249 100644 --- a/xpinstall/wizard/unix/src2/nsInstallDlg.cpp +++ b/xpinstall/wizard/unix/src2/nsInstallDlg.cpp @@ -69,6 +69,8 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData) { DUMP("Next"); int err = OK; + int bCus; + nsComponentList *comps = NULL; pthread_t ength; pthread_t *me = (pthread_t *) malloc(sizeof(pthread_t)); @@ -79,16 +81,25 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData) return; } + bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1)); + comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents(); + // initialize progress bar cleanly - gtk_label_set_text(GTK_LABEL(sMajorLabel), DOWNLOADING); - gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE); + if (nsXIEngine::ExistAllXPIs(bCus, comps)) + gtk_label_set_text(GTK_LABEL(sMajorLabel), PREPARING); + else + gtk_label_set_text(GTK_LABEL(sMajorLabel), DOWNLOADING); + gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), TRUE); gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), 1); gtk_widget_show(sMajorLabel); gtk_widget_show(sMajorProgBar); gtk_widget_hide(gCtx->back); gtk_widget_hide(gCtx->next); - // XXX hide msg0? + gtk_widget_hide(sMsg0Label); + + pthread_mutex_init(&gCtx->prog_mutex, NULL); + pthread_cond_init(&gCtx->prog_cv, NULL); *me = pthread_self(); pthread_create(&ength, NULL, WorkDammitWork, (void*) me); @@ -147,7 +158,6 @@ int nsInstallDlg::Show(int aDirection) { int err = OK; - GtkWidget *msg0 = NULL; GtkWidget *hbox = NULL; GtkWidget *vbox = NULL; @@ -163,13 +173,13 @@ nsInstallDlg::Show(int aDirection) gtk_widget_show(mTable); // insert a static text widget in the first row - msg0 = gtk_label_new(mMsg0); + sMsg0Label = gtk_label_new(mMsg0); hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), msg0, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), sMsg0Label, FALSE, FALSE, 0); gtk_widget_show(hbox); gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL, 20, 20); - gtk_widget_show(msg0); + gtk_widget_show(sMsg0Label); // vbox with two widgets packed in: label0 / progmeter0 (major) vbox = gtk_vbox_new(FALSE, 0); @@ -322,11 +332,17 @@ static int bInstallStarted = FALSE; gint nsInstallDlg::ProgressUpdater(gpointer aData) { + int status = 0; + + while (gtk_events_pending()) + gtk_main_iteration(); + switch (sActivity) { case nsInstallDlg::ACT_DOWNLOAD: // DUMP("Downloading..."); - return 1; + status = 1; + break; case nsInstallDlg::ACT_EXTRACT: // DUMP("Extracting..."); @@ -337,7 +353,8 @@ nsInstallDlg::ProgressUpdater(gpointer aData) bExtractStarted = TRUE; } - return 1; + status = 1; + break; case nsInstallDlg::ACT_INSTALL: // DUMP("Installing..."); @@ -348,13 +365,27 @@ nsInstallDlg::ProgressUpdater(gpointer aData) bInstallStarted = TRUE; } - return 1; + + pthread_mutex_lock(&gCtx->prog_mutex); + while (gCtx->threadTurn != nsXIContext::UI_THREAD) + pthread_cond_wait(&gCtx->prog_cv, &gCtx->prog_mutex); + + gtk_widget_show(sMinorLabel); + gtk_widget_show(sMinorProgBar); + gtk_widget_draw(sMinorLabel, NULL); + gtk_widget_draw(sMinorProgBar, NULL); + + gCtx->threadTurn = nsXIContext::ENGINE_THREAD; + pthread_mutex_unlock(&gCtx->prog_mutex); + + status = 1; + break; default: break; } - return 0; + return status; } void @@ -362,21 +393,34 @@ nsInstallDlg::XPIProgressCB(const char *aMsg, int aVal, int aMax) { // DUMP("XPIProgressCB"); - gtk_label_set_text(GTK_LABEL(sMinorLabel), aMsg); - gtk_widget_show(sMinorLabel); + char msg[32]; if (aMax != 0) { gfloat percent = aVal/aMax; +#ifdef DEBUG + printf("progress percent: %f\n", percent); +#endif + gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), FALSE); gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent); gtk_widget_show(sMinorProgBar); + + sprintf(msg, "Processing file %d of %d", aVal, aMax); + gtk_label_set_text(GTK_LABEL(sMinorLabel), msg); } else { - gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), FALSE); - // gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), 1); + gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), TRUE); + gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), 1); gtk_widget_show(sMinorProgBar); + + gtk_label_set_text(GTK_LABEL(sMinorLabel), aMsg); } + + gtk_widget_show(sMinorLabel); + + while (gtk_events_pending()) + gtk_main_iteration(); } void diff --git a/xpinstall/wizard/unix/src2/nsInstallDlg.h b/xpinstall/wizard/unix/src2/nsInstallDlg.h index 82af503ad04..04997b15198 100644 --- a/xpinstall/wizard/unix/src2/nsInstallDlg.h +++ b/xpinstall/wizard/unix/src2/nsInstallDlg.h @@ -70,6 +70,7 @@ private: }; static char *sXPInstallEngine; +static GtkWidget *sMsg0Label; static GtkWidget *sMajorLabel; static GtkWidget *sMinorLabel; static GtkWidget *sMajorProgBar; diff --git a/xpinstall/wizard/unix/src2/nsXIContext.cpp b/xpinstall/wizard/unix/src2/nsXIContext.cpp index e5e26005e7d..26456964294 100644 --- a/xpinstall/wizard/unix/src2/nsXIContext.cpp +++ b/xpinstall/wizard/unix/src2/nsXIContext.cpp @@ -49,6 +49,8 @@ nsXIContext::nsXIContext() backID = 0; nextID = 0; bMoving = FALSE; + + threadTurn = nsXIContext::UI_THREAD; } nsXIContext::~nsXIContext() diff --git a/xpinstall/wizard/unix/src2/nsXIContext.h b/xpinstall/wizard/unix/src2/nsXIContext.h index 0508ef6f4cc..608a69dc24d 100644 --- a/xpinstall/wizard/unix/src2/nsXIContext.h +++ b/xpinstall/wizard/unix/src2/nsXIContext.h @@ -26,6 +26,7 @@ #define _NS_XICONTEXT_H_ #include +#include #include "nsLicenseDlg.h" #include "nsWelcomeDlg.h" @@ -75,6 +76,16 @@ public: int nextID; /* signal handler id for next btn */ int bMoving; /* when moving between dlgs signals are emitted twice; this notes the state */ + + pthread_mutex_t prog_mutex; /* mutex for sync between ui and eng th */ + pthread_cond_t prog_cv; /* cond var for ui/eng th communication */ + int threadTurn; /* toggle between engine and ui threads */ + enum + { + UI_THREAD = 0x0A, + ENGINE_THREAD = 0x0F + }; + /*-------------------------------------------------------------------* * Utilities *-------------------------------------------------------------------*/ diff --git a/xpinstall/wizard/unix/src2/nsXIEngine.cpp b/xpinstall/wizard/unix/src2/nsXIEngine.cpp index fb89b632b03..292656b6d8f 100644 --- a/xpinstall/wizard/unix/src2/nsXIEngine.cpp +++ b/xpinstall/wizard/unix/src2/nsXIEngine.cpp @@ -45,7 +45,7 @@ nsXIEngine::~nsXIEngine() int nsXIEngine::Download(int aCustom, nsComponentList *aComps) { - // DUMP("Download"); + DUMP("Download"); if (!aComps) return E_PARAM; @@ -62,6 +62,10 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) if (!mTmp || err != OK) return E_DIR_CREATE; + // if all .xpis exist in the ./xpi dir (blob/CD) we don't need to download + if (ExistAllXPIs(aCustom, aComps)) + return CopyToTmp(aCustom, aComps); + while (currComp) { if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) @@ -91,7 +95,7 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps) int nsXIEngine::Extract(nsComponent *aXPIEngine) { - // DUMP("Extract"); + DUMP("Extract"); char path[1024]; char bindir[512]; @@ -109,7 +113,7 @@ nsXIEngine::Extract(nsComponent *aXPIEngine) for (i = 0; i < CORE_LIB_COUNT*2; i++) { - sprintf(unzipcmd, "unzip %s -d %s %s%s", + sprintf(unzipcmd, "unzip %s -d %s %s%s > /dev/null", path, mTmp, sCoreLibs[i], sCoreLibs[i+1]); i++; system(unzipcmd); @@ -119,25 +123,19 @@ nsXIEngine::Extract(nsComponent *aXPIEngine) if (-1 == stat(bindir, &dummy)) return E_EXTRACTION; - // XXX remove this code when done -#if 0 - // move files to cwd - memset(mvcmd, 0, 512); - sprintf(mvcmd, "mv %s/* .", bindir); - system(mvcmd); -#endif - return OK; } int nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination) { - // DUMP("Install"); + DUMP("Install"); int err = OK; xpistub_t stub; char cmd[1024]; + char *old_LD_LIBRARY_PATH = NULL; + char new_LD_LIBRARY_PATH[256]; int i; int compNum = 1; int totalComps; @@ -146,6 +144,13 @@ nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination) if (!aComps || !aDestination) return E_PARAM; + // handle LD_LIBRARY_PATH settings + memset(new_LD_LIBRARY_PATH, 0, 256); + sprintf(new_LD_LIBRARY_PATH, "%s/bin:.", mTmp); + DUMP(new_LD_LIBRARY_PATH); + old_LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH"); + setenv("LD_LIBRARY_PATH", new_LD_LIBRARY_PATH, 1); + if (aCustom) totalComps = aComps->GetLengthSelected(); else @@ -177,15 +182,8 @@ nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination) UnloadXPIStub(&stub); - // --> now in {ROOT}/.tmp.xi.N/bin -#if 0 - // rm libs and components dir --> now in {ROOT}/.tmp.xi.N/ - chdir(".."); - for (i=1; i now in {ROOT}/ chdir("../.."); @@ -205,14 +203,20 @@ nsXIEngine::MakeUniqueTmpDir() { int err = OK; int i; - char buf[2048]; - char cmd[2054]; + char buf[1024]; + char cwd[1024]; + char cmd[1030]; struct stat dummy; mTmp = NULL; + memset(cwd, 0, 1024); + if (!getcwd(cwd, 1024)) + return E_MEM; + for (i = 0; i < MAX_TMP_DIRS; i++) { - sprintf(buf, TMP_DIR_TEMPLATE, i); + memset(buf, 0, 1024); + sprintf(buf, TMP_DIR_TEMPLATE, cwd, i); if (-1 == stat(buf, &dummy)) break; } @@ -327,7 +331,11 @@ nsXIEngine::LoadXPIStub(xpistub_t *aStub, char *aDestination) memset(libpath, 0, 1024); getcwd(libpath, 1024); sprintf(libpath, "%s/%s", libpath, XPISTUB); + +#ifdef DEBUG printf("DEBUG: libpath = >>%s<<\n", libpath); +#endif + aStub->handle = NULL; aStub->handle = dlopen(libpath, RTLD_LAZY); if (!aStub->handle) @@ -352,7 +360,11 @@ printf("DEBUG: libpath = >>%s<<\n", libpath); DUMP("xpistub symbols loaded"); rv = aStub->fn_init(aDestination, ProgressCallback); + +#ifdef DEBUG printf("DEBUG: XPI_Init returned 0x%.8X\n", rv); +#endif + DUMP("XPI_Init called"); if (NS_FAILED(rv)) { @@ -383,7 +395,11 @@ nsXIEngine::InstallXPI(nsComponent *aXPI, xpistub_t *aStub) #define XPI_NO_NEW_THREAD 0x1000 rv = aStub->fn_install(xpipath, "", XPI_NO_NEW_THREAD); + +#ifdef DEBUG printf("DEBUG: XPI_Install %s returned %d\n", aXPI->GetArchive(), rv); +#endif + if (!NS_SUCCEEDED(rv)) err = E_INSTALL; @@ -423,10 +439,65 @@ BAIL: } void -nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aMax, PRInt32 aVal) +nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax) { // DUMP("ProgressCallback"); - nsInstallDlg::XPIProgressCB(aMsg, (int)aMax, (int)aVal); - usleep(10); + pthread_mutex_lock(&gCtx->prog_mutex); + + nsInstallDlg::XPIProgressCB(aMsg, (int)aVal, (int)aMax); + + gCtx->threadTurn = nsXIContext::UI_THREAD; + + pthread_cond_signal(&gCtx->prog_cv); + pthread_mutex_unlock(&gCtx->prog_mutex); +} + +int +nsXIEngine::ExistAllXPIs(int aCustom, nsComponentList *aComps) +{ + int bAllExist = TRUE; + nsComponent *currComp = aComps->GetHead(); + char currArchivePath[256]; + struct stat dummy; + + while (currComp) + { + if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) + { + memset(currArchivePath, 0, 256); + sprintf(currArchivePath, "%s/%s", XPI_DIR, currComp->GetArchive()); + DUMP(currArchivePath); + + if (0 != stat(currArchivePath, &dummy)) + return FALSE; + } + + currComp = currComp->GetNext(); + } + + return bAllExist; +} + +int +nsXIEngine::CopyToTmp(int aCustom, nsComponentList *aComps) +{ + int err = OK; + nsComponent *currComp = aComps->GetHead(); + char cmd[256]; + + while (currComp) + { + if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) + { + memset(cmd, 0, 256); + sprintf(cmd, "cp %s/%s %s", XPI_DIR, currComp->GetArchive(), mTmp); + DUMP(cmd); + system(cmd); + } + + currComp = currComp->GetNext(); + } + + return err; } diff --git a/xpinstall/wizard/unix/src2/nsXIEngine.h b/xpinstall/wizard/unix/src2/nsXIEngine.h index a964db350ff..c02ff22533b 100644 --- a/xpinstall/wizard/unix/src2/nsXIEngine.h +++ b/xpinstall/wizard/unix/src2/nsXIEngine.h @@ -73,7 +73,8 @@ public: int Extract(nsComponent *aXPIEngine); int Install(int aCustom, nsComponentList *aComps, char *aDestination); - static void ProgressCallback(const char* aMsg, PRInt32 aMax, PRInt32 aVal); + static void ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax); + static int ExistAllXPIs(int aCustom, nsComponentList *aComps); private: int MakeUniqueTmpDir(); @@ -82,8 +83,9 @@ private: int LoadXPIStub(xpistub_t *aStub, char *aDestionation); int InstallXPI(nsComponent *aComp, xpistub_t *aStub); int UnloadXPIStub(xpistub_t *aStub); + int CopyToTmp(int aCustom, nsComponentList *aComps); - char *mTmp; + char *mTmp; }; #define CORE_LIB_COUNT 9