* 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
This commit is contained in:
sgehani%netscape.com 2000-04-05 05:16:05 +00:00
Родитель f0f156d3f3
Коммит 83c1ecb571
9 изменённых файлов: 181 добавлений и 47 удалений

Просмотреть файл

@ -28,7 +28,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
PROGRAM = MozInstaller PROGRAM = mozilla-installer
CPPSRCS = \ CPPSRCS = \
nsXInstallerDlg.cpp \ nsXInstallerDlg.cpp \

Просмотреть файл

@ -42,6 +42,7 @@
#define SELECT_DIR "Select a directory" #define SELECT_DIR "Select a directory"
#define DESCRIPTION "Description" #define DESCRIPTION "Description"
#define DOWNLOADING "Downloading..." #define DOWNLOADING "Downloading..."
#define PREPARING "Preparing installer modules..."
#define EXTRACTING "Extracting installer files..." #define EXTRACTING "Extracting installer files..."
#define INSTALLING "Installing" #define INSTALLING "Installing"
@ -105,8 +106,9 @@
/*--------------------------------------------------------------------* /*--------------------------------------------------------------------*
* Macros * Macros
*--------------------------------------------------------------------*/ *--------------------------------------------------------------------*/
#define TMP_DIR_TEMPLATE "./.tmp.xi.%d" #define TMP_DIR_TEMPLATE "%s/.tmp.xi.%d" // <cwd>/.tmp.xi.<N>
#define TMP_EXTRACT_SUBDIR "bin" #define TMP_EXTRACT_SUBDIR "bin"
#define XPI_DIR "./xpi"
#define XPISTUB "libxpistub.so" #define XPISTUB "libxpistub.so"
#define FN_INIT "XPI_Init" #define FN_INIT "XPI_Init"

Просмотреть файл

@ -53,7 +53,8 @@
E_LIB_OPEN = -418, /* couldn't open stub lib */ E_LIB_OPEN = -418, /* couldn't open stub lib */
E_LIB_SYM = -419, /* couldn't get symbol in lib */ E_LIB_SYM = -419, /* couldn't get symbol in lib */
E_XPI_FAIL = -420, /* a xpistub call failed */ 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 */ #define FATAL_ERR_THRESHOLD -500 /* errs below this cause app quit */

Просмотреть файл

@ -69,6 +69,8 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData)
{ {
DUMP("Next"); DUMP("Next");
int err = OK; int err = OK;
int bCus;
nsComponentList *comps = NULL;
pthread_t ength; pthread_t ength;
pthread_t *me = (pthread_t *) malloc(sizeof(pthread_t)); pthread_t *me = (pthread_t *) malloc(sizeof(pthread_t));
@ -79,16 +81,25 @@ nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData)
return; return;
} }
bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
// initialize progress bar cleanly // initialize progress bar cleanly
gtk_label_set_text(GTK_LABEL(sMajorLabel), DOWNLOADING); if (nsXIEngine::ExistAllXPIs(bCus, comps))
gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE); 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_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), 1);
gtk_widget_show(sMajorLabel); gtk_widget_show(sMajorLabel);
gtk_widget_show(sMajorProgBar); gtk_widget_show(sMajorProgBar);
gtk_widget_hide(gCtx->back); gtk_widget_hide(gCtx->back);
gtk_widget_hide(gCtx->next); 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(); *me = pthread_self();
pthread_create(&ength, NULL, WorkDammitWork, (void*) me); pthread_create(&ength, NULL, WorkDammitWork, (void*) me);
@ -147,7 +158,6 @@ int
nsInstallDlg::Show(int aDirection) nsInstallDlg::Show(int aDirection)
{ {
int err = OK; int err = OK;
GtkWidget *msg0 = NULL;
GtkWidget *hbox = NULL; GtkWidget *hbox = NULL;
GtkWidget *vbox = NULL; GtkWidget *vbox = NULL;
@ -163,13 +173,13 @@ nsInstallDlg::Show(int aDirection)
gtk_widget_show(mTable); gtk_widget_show(mTable);
// insert a static text widget in the first row // 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); 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_widget_show(hbox);
gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 1, 2, gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 1, 2,
GTK_FILL | GTK_EXPAND, GTK_FILL, 20, 20); 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 with two widgets packed in: label0 / progmeter0 (major)
vbox = gtk_vbox_new(FALSE, 0); vbox = gtk_vbox_new(FALSE, 0);
@ -322,11 +332,17 @@ static int bInstallStarted = FALSE;
gint gint
nsInstallDlg::ProgressUpdater(gpointer aData) nsInstallDlg::ProgressUpdater(gpointer aData)
{ {
int status = 0;
while (gtk_events_pending())
gtk_main_iteration();
switch (sActivity) switch (sActivity)
{ {
case nsInstallDlg::ACT_DOWNLOAD: case nsInstallDlg::ACT_DOWNLOAD:
// DUMP("Downloading..."); // DUMP("Downloading...");
return 1; status = 1;
break;
case nsInstallDlg::ACT_EXTRACT: case nsInstallDlg::ACT_EXTRACT:
// DUMP("Extracting..."); // DUMP("Extracting...");
@ -337,7 +353,8 @@ nsInstallDlg::ProgressUpdater(gpointer aData)
bExtractStarted = TRUE; bExtractStarted = TRUE;
} }
return 1; status = 1;
break;
case nsInstallDlg::ACT_INSTALL: case nsInstallDlg::ACT_INSTALL:
// DUMP("Installing..."); // DUMP("Installing...");
@ -348,13 +365,27 @@ nsInstallDlg::ProgressUpdater(gpointer aData)
bInstallStarted = TRUE; 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: default:
break; break;
} }
return 0; return status;
} }
void void
@ -362,21 +393,34 @@ nsInstallDlg::XPIProgressCB(const char *aMsg, int aVal, int aMax)
{ {
// DUMP("XPIProgressCB"); // DUMP("XPIProgressCB");
gtk_label_set_text(GTK_LABEL(sMinorLabel), aMsg); char msg[32];
gtk_widget_show(sMinorLabel);
if (aMax != 0) if (aMax != 0)
{ {
gfloat percent = aVal/aMax; 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_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent);
gtk_widget_show(sMinorProgBar); gtk_widget_show(sMinorProgBar);
sprintf(msg, "Processing file %d of %d", aVal, aMax);
gtk_label_set_text(GTK_LABEL(sMinorLabel), msg);
} }
else else
{ {
gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), FALSE); gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), TRUE);
// gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), 1); gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), 1);
gtk_widget_show(sMinorProgBar); gtk_widget_show(sMinorProgBar);
gtk_label_set_text(GTK_LABEL(sMinorLabel), aMsg);
} }
gtk_widget_show(sMinorLabel);
while (gtk_events_pending())
gtk_main_iteration();
} }
void void

Просмотреть файл

@ -70,6 +70,7 @@ private:
}; };
static char *sXPInstallEngine; static char *sXPInstallEngine;
static GtkWidget *sMsg0Label;
static GtkWidget *sMajorLabel; static GtkWidget *sMajorLabel;
static GtkWidget *sMinorLabel; static GtkWidget *sMinorLabel;
static GtkWidget *sMajorProgBar; static GtkWidget *sMajorProgBar;

Просмотреть файл

@ -49,6 +49,8 @@ nsXIContext::nsXIContext()
backID = 0; backID = 0;
nextID = 0; nextID = 0;
bMoving = FALSE; bMoving = FALSE;
threadTurn = nsXIContext::UI_THREAD;
} }
nsXIContext::~nsXIContext() nsXIContext::~nsXIContext()

Просмотреть файл

@ -26,6 +26,7 @@
#define _NS_XICONTEXT_H_ #define _NS_XICONTEXT_H_
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <pthread.h>
#include "nsLicenseDlg.h" #include "nsLicenseDlg.h"
#include "nsWelcomeDlg.h" #include "nsWelcomeDlg.h"
@ -75,6 +76,16 @@ public:
int nextID; /* signal handler id for next btn */ int nextID; /* signal handler id for next btn */
int bMoving; /* when moving between dlgs signals are int bMoving; /* when moving between dlgs signals are
emitted twice; this notes the state */ 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 * Utilities
*-------------------------------------------------------------------*/ *-------------------------------------------------------------------*/

Просмотреть файл

@ -45,7 +45,7 @@ nsXIEngine::~nsXIEngine()
int int
nsXIEngine::Download(int aCustom, nsComponentList *aComps) nsXIEngine::Download(int aCustom, nsComponentList *aComps)
{ {
// DUMP("Download"); DUMP("Download");
if (!aComps) if (!aComps)
return E_PARAM; return E_PARAM;
@ -62,6 +62,10 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
if (!mTmp || err != OK) if (!mTmp || err != OK)
return E_DIR_CREATE; 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) while (currComp)
{ {
if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) ) if ( (aCustom == TRUE && currComp->IsSelected()) || (aCustom == FALSE) )
@ -91,7 +95,7 @@ nsXIEngine::Download(int aCustom, nsComponentList *aComps)
int int
nsXIEngine::Extract(nsComponent *aXPIEngine) nsXIEngine::Extract(nsComponent *aXPIEngine)
{ {
// DUMP("Extract"); DUMP("Extract");
char path[1024]; char path[1024];
char bindir[512]; char bindir[512];
@ -109,7 +113,7 @@ nsXIEngine::Extract(nsComponent *aXPIEngine)
for (i = 0; i < CORE_LIB_COUNT*2; i++) 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]); path, mTmp, sCoreLibs[i], sCoreLibs[i+1]);
i++; i++;
system(unzipcmd); system(unzipcmd);
@ -119,25 +123,19 @@ nsXIEngine::Extract(nsComponent *aXPIEngine)
if (-1 == stat(bindir, &dummy)) if (-1 == stat(bindir, &dummy))
return E_EXTRACTION; 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; return OK;
} }
int int
nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination) nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination)
{ {
// DUMP("Install"); DUMP("Install");
int err = OK; int err = OK;
xpistub_t stub; xpistub_t stub;
char cmd[1024]; char cmd[1024];
char *old_LD_LIBRARY_PATH = NULL;
char new_LD_LIBRARY_PATH[256];
int i; int i;
int compNum = 1; int compNum = 1;
int totalComps; int totalComps;
@ -146,6 +144,13 @@ nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination)
if (!aComps || !aDestination) if (!aComps || !aDestination)
return E_PARAM; 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) if (aCustom)
totalComps = aComps->GetLengthSelected(); totalComps = aComps->GetLengthSelected();
else else
@ -177,15 +182,8 @@ nsXIEngine::Install(int aCustom, nsComponentList *aComps, char *aDestination)
UnloadXPIStub(&stub); UnloadXPIStub(&stub);
// --> now in {ROOT}/.tmp.xi.N/bin // restore LD_LIBRARY_PATH settings
#if 0 setenv("LD_LIBRARY_PATH", old_LD_LIBRARY_PATH, 1);
// rm libs and components dir --> now in {ROOT}/.tmp.xi.N/
chdir("..");
for (i=1; i<CORE_LIB_COUNT*2; i+=2)
{
unlink(sCoreLibs[i]);
}
#endif
// rm tmp dir --> now in {ROOT}/ // rm tmp dir --> now in {ROOT}/
chdir("../.."); chdir("../..");
@ -205,14 +203,20 @@ nsXIEngine::MakeUniqueTmpDir()
{ {
int err = OK; int err = OK;
int i; int i;
char buf[2048]; char buf[1024];
char cmd[2054]; char cwd[1024];
char cmd[1030];
struct stat dummy; struct stat dummy;
mTmp = NULL; mTmp = NULL;
memset(cwd, 0, 1024);
if (!getcwd(cwd, 1024))
return E_MEM;
for (i = 0; i < MAX_TMP_DIRS; i++) 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)) if (-1 == stat(buf, &dummy))
break; break;
} }
@ -327,7 +331,11 @@ nsXIEngine::LoadXPIStub(xpistub_t *aStub, char *aDestination)
memset(libpath, 0, 1024); memset(libpath, 0, 1024);
getcwd(libpath, 1024); getcwd(libpath, 1024);
sprintf(libpath, "%s/%s", libpath, XPISTUB); sprintf(libpath, "%s/%s", libpath, XPISTUB);
#ifdef DEBUG
printf("DEBUG: libpath = >>%s<<\n", libpath); printf("DEBUG: libpath = >>%s<<\n", libpath);
#endif
aStub->handle = NULL; aStub->handle = NULL;
aStub->handle = dlopen(libpath, RTLD_LAZY); aStub->handle = dlopen(libpath, RTLD_LAZY);
if (!aStub->handle) if (!aStub->handle)
@ -352,7 +360,11 @@ printf("DEBUG: libpath = >>%s<<\n", libpath);
DUMP("xpistub symbols loaded"); DUMP("xpistub symbols loaded");
rv = aStub->fn_init(aDestination, ProgressCallback); rv = aStub->fn_init(aDestination, ProgressCallback);
#ifdef DEBUG
printf("DEBUG: XPI_Init returned 0x%.8X\n", rv); printf("DEBUG: XPI_Init returned 0x%.8X\n", rv);
#endif
DUMP("XPI_Init called"); DUMP("XPI_Init called");
if (NS_FAILED(rv)) if (NS_FAILED(rv))
{ {
@ -383,7 +395,11 @@ nsXIEngine::InstallXPI(nsComponent *aXPI, xpistub_t *aStub)
#define XPI_NO_NEW_THREAD 0x1000 #define XPI_NO_NEW_THREAD 0x1000
rv = aStub->fn_install(xpipath, "", XPI_NO_NEW_THREAD); rv = aStub->fn_install(xpipath, "", XPI_NO_NEW_THREAD);
#ifdef DEBUG
printf("DEBUG: XPI_Install %s returned %d\n", aXPI->GetArchive(), rv); printf("DEBUG: XPI_Install %s returned %d\n", aXPI->GetArchive(), rv);
#endif
if (!NS_SUCCEEDED(rv)) if (!NS_SUCCEEDED(rv))
err = E_INSTALL; err = E_INSTALL;
@ -423,10 +439,65 @@ BAIL:
} }
void void
nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aMax, PRInt32 aVal) nsXIEngine::ProgressCallback(const char* aMsg, PRInt32 aVal, PRInt32 aMax)
{ {
// DUMP("ProgressCallback"); // DUMP("ProgressCallback");
nsInstallDlg::XPIProgressCB(aMsg, (int)aMax, (int)aVal); pthread_mutex_lock(&gCtx->prog_mutex);
usleep(10);
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;
} }

Просмотреть файл

@ -73,7 +73,8 @@ public:
int Extract(nsComponent *aXPIEngine); int Extract(nsComponent *aXPIEngine);
int Install(int aCustom, nsComponentList *aComps, char *aDestination); 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: private:
int MakeUniqueTmpDir(); int MakeUniqueTmpDir();
@ -82,8 +83,9 @@ private:
int LoadXPIStub(xpistub_t *aStub, char *aDestionation); int LoadXPIStub(xpistub_t *aStub, char *aDestionation);
int InstallXPI(nsComponent *aComp, xpistub_t *aStub); int InstallXPI(nsComponent *aComp, xpistub_t *aStub);
int UnloadXPIStub(xpistub_t *aStub); int UnloadXPIStub(xpistub_t *aStub);
int CopyToTmp(int aCustom, nsComponentList *aComps);
char *mTmp; char *mTmp;
}; };
#define CORE_LIB_COUNT 9 #define CORE_LIB_COUNT 9