diff options
author | wtc%netscape.com <devnull@localhost> | 1999-03-02 00:58:34 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 1999-03-02 00:58:34 +0000 |
commit | 45c8684d940dfeab4891550f8d0662b49547701b (patch) | |
tree | 14146e0b29d229d37a195165754924fc61cd1016 | |
parent | c5742d6455413019013f14c201c6994fa6643669 (diff) | |
download | nspr-hg-45c8684d940dfeab4891550f8d0662b49547701b.tar.gz |
Another update from the internal CVS repository /m/src to mozilla.org.
-rw-r--r-- | config/rules.mk | 4 | ||||
-rw-r--r-- | pr/include/MANIFEST | 2 | ||||
-rw-r--r-- | pr/include/nspr.h | 2 | ||||
-rw-r--r-- | pr/include/prerr.h | 4 | ||||
-rw-r--r-- | pr/include/prerror.h | 76 | ||||
-rw-r--r-- | pr/include/prerrorinstall.h (renamed from pr/include/prerrorplugin.h) | 82 | ||||
-rw-r--r-- | pr/include/private/primpl.h | 1 | ||||
-rw-r--r-- | pr/src/Makefile | 2 | ||||
-rw-r--r-- | pr/src/io/prfile.c | 36 | ||||
-rw-r--r-- | pr/src/misc/compile-et.pl | 4 | ||||
-rw-r--r-- | pr/src/misc/prerr.c | 24 | ||||
-rw-r--r-- | pr/src/misc/prerr.et | 2 | ||||
-rw-r--r-- | pr/src/misc/prerrortable.c | 66 | ||||
-rw-r--r-- | pr/src/misc/prinit.c | 47 | ||||
-rw-r--r-- | pr/src/nspr.rc | 84 | ||||
-rw-r--r-- | pr/src/pthreads/ptthread.c | 47 | ||||
-rw-r--r-- | pr/src/resource.h | 16 | ||||
-rw-r--r-- | pr/src/threads/prrwlock.c | 207 | ||||
-rw-r--r-- | pr/tests/Makefile | 6 | ||||
-rw-r--r-- | pr/tests/errcodes.c | 148 | ||||
-rw-r--r-- | pr/tests/rwlocktest.c | 28 | ||||
-rw-r--r-- | pr/tests/socket.c | 105 | ||||
-rw-r--r-- | pr/tests/testfile.c | 230 |
23 files changed, 939 insertions, 284 deletions
diff --git a/config/rules.mk b/config/rules.mk index 1c95360d..fed8e8fb 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -321,8 +321,12 @@ $(RES): $(RESNAME) ifeq ($(OS_TARGET),OS2) $(RC) -DOS2 -r $(RESNAME) $(RES) else +ifeq ($(OS_TARGET),WINNT) + $(RC) -dWINNT -Fo$(RES) $(RESNAME) +else $(RC) -Fo$(RES) $(RESNAME) endif +endif @echo $(RES) finished endif diff --git a/pr/include/MANIFEST b/pr/include/MANIFEST index 769830a0..87fd5324 100644 --- a/pr/include/MANIFEST +++ b/pr/include/MANIFEST @@ -13,7 +13,7 @@ prdtoa.h prenv.h prerr.h prerror.h -prerrorplugin.h +prerrorinstall.h prinet.h prinit.h prinrval.h diff --git a/pr/include/nspr.h b/pr/include/nspr.h index 17cfdfd3..f385f50e 100644 --- a/pr/include/nspr.h +++ b/pr/include/nspr.h @@ -27,7 +27,7 @@ #include "prdtoa.h" #include "prenv.h" #include "prerror.h" -#include "prerrorplugin.h" +#include "prerrorinstall.h" #include "prinet.h" #include "prinit.h" #include "prinrval.h" diff --git a/pr/include/prerr.h b/pr/include/prerr.h index 5fdc8236..484c52d9 100644 --- a/pr/include/prerr.h +++ b/pr/include/prerr.h @@ -89,7 +89,7 @@ #define PR_END_OF_FILE_ERROR (-5938L) #define PR_FILE_SEEK_ERROR (-5937L) #define PR_FILE_IS_BUSY_ERROR (-5936L) -#define PR_RESERVED_ERROR (-5935L) +#define PR_RESERVED_ERROR_5935 (-5935L) #define PR_IN_PROGRESS_ERROR (-5934L) #define PR_ALREADY_INITIATED_ERROR (-5933L) #define PR_GROUP_EMPTY_ERROR (-5932L) @@ -99,7 +99,7 @@ #define PR_CONNECT_ABORTED_ERROR (-5928L) #define PR_HOST_UNREACHABLE_ERROR (-5927L) #define PR_MAX_ERROR (-5926L) -extern void pr_init_error_table_nspr(void); +extern void nspr_InitializePRErrorTable(void); #define ERROR_TABLE_BASE_nspr (-6000L) #endif /* prerr_h___ */ diff --git a/pr/include/prerror.h b/pr/include/prerror.h index eeb31c58..eaf87170 100644 --- a/pr/include/prerror.h +++ b/pr/include/prerror.h @@ -94,39 +94,43 @@ purpose. It is provided "as is" without express or implied warranty. ** Description: Localizable error code to string function. ** ** -** NSPR provides a mechanism for converting an error code to a descriptive -** string, in a caller-specified language. +** NSPR provides a mechanism for converting an error code to a +** descriptive string, in a caller-specified language. ** -** Error codes themselves are 32 bit (signed) integers. Typically, the high -** order 24 bits are an identifier of which error table the error code is -** from, and the low order 8 bits are a sequential error number within -** the table. NSPR supports error tables whose first error code is not -** a multiple of 256, such error code assignments should be avoided when -** possible. +** Error codes themselves are 32 bit (signed) integers. Typically, +** the high order 24 bits are an identifier of which error table the +** error code is from, and the low order 8 bits are a sequential error +** number within the table. NSPR supports error tables whose first +** error code is not a multiple of 256, such error code assignments +** should be avoided when possible. ** ** Error table 0 is defined to match the UNIX system call error table ** (sys_errlist); this allows errno values to be used directly in the -** library. Other error table numbers are typically formed by compacting -** together the first four characters of the error table name. The mapping -** between characters in the name and numeric values in the error code are -** defined in a system-independent fashion, so that two systems that can -** pass integral values between them can reliably pass error codes without -** loss of meaning; this should work even if the character sets used are not -** the same. (However, if this is to be done, error table 0 should be avoided, -** since the local system call error tables may differ.) +** library. Other error table numbers are typically formed by +** compacting together the first four characters of the error table +** name. The mapping between characters in the name and numeric +** values in the error code are defined in a system-independent +** fashion, so that two systems that can pass integral values between +** them can reliably pass error codes without loss of meaning; this +** should work even if the character sets used are not the +** same. (However, if this is to be done, error table 0 should be +** avoided, since the local system call error tables may differ.) ** -** Libraries defining error codes need only provide a table mapping error -** code numbers to names and default English descriptions, calling a routine -** to make the table ``known'' to NSPR library. Any error code the library -** generates can be converted to the corresponding error message. There is -** also a default format for error codes accidentally returned before making -** the table known, which is of the form "unknown code foo 32", where "foo" -** would be the name of the table. +** Libraries defining error codes need only provide a table mapping +** error code numbers to names and default English descriptions, +** calling a routine to install the table, making it ``known'' to NSPR +** library. Once installed, a table may not be removed. Any error +** code the library generates can be converted to the corresponding +** error message. There is also a default format for error codes +** accidentally returned before making the table known, which is of +** the form "unknown code foo 32", where "foo" would be the name of +** the table. ** -** Normally, the error code conversion routine only supports the languages -** "i-default" and "en", returning the error-table-provided English -** description for both languages. The application may provide a -** localization plugin, allowing support for additional languages. +** Normally, the error code conversion routine only supports the +** languages "i-default" and "en", returning the error-table-provided +** English description for both languages. The application may +** provide a localization plugin, allowing support for additional +** languages. ** **/ @@ -143,7 +147,7 @@ purpose. It is provided "as is" without express or implied warranty. * which has been explicitly negotiated. Additional language * codes are defined by an application-provided localization plugin. */ -typedef PRInt32 PRLanguageCode; +typedef PRUint32 PRLanguageCode; #define PR_LANGUAGE_I_DEFAULT 0 /* i-default, the default language */ #define PR_LANGUAGE_EN 1 /* English, explicitly negotiated */ @@ -152,7 +156,7 @@ typedef PRInt32 PRLanguageCode; /**********************************************************************/ /*********************************************************************** -** FUNCTION: PR_ErrorTableToString +** FUNCTION: PR_ErrorToString ** DESCRIPTION: ** Returns the UTF-8 message for an error code in ** the requested language. May return the message @@ -164,6 +168,20 @@ typedef PRInt32 PRLanguageCode; PR_EXTERN(const char *) PR_ErrorToString(PRErrorCode code, PRLanguageCode language); + +/*********************************************************************** +** FUNCTION: PR_ErrorToName +** DESCRIPTION: +** Returns the macro name for an error code, or NULL +** if the error code is not known. The returned string is +** valid for the duration of the process. +** +** Does not work for error table 0, the system error codes. +** +***********************************************************************/ +PR_EXTERN(const char *) PR_ErrorToName(PRErrorCode code); + + /*********************************************************************** ** FUNCTION: PR_ErrorLanguages ** DESCRIPTION: diff --git a/pr/include/prerrorplugin.h b/pr/include/prerrorinstall.h index c33defc0..2ce2312c 100644 --- a/pr/include/prerrorplugin.h +++ b/pr/include/prerrorinstall.h @@ -15,8 +15,8 @@ * Reserved. */ -#ifndef prerrorplugin_h___ -#define prerrorplugin_h___ +#ifndef prerrorinstall_h___ +#define prerrorinstall_h___ #include "prerror.h" @@ -27,15 +27,22 @@ PR_BEGIN_EXTERN_C /**********************************************************************/ /* + * struct PRErrorMessage -- + * + * An error message in an error table. + */ +struct PRErrorMessage { + const char * name; /* Macro name for error */ + const char * en_text; /* Default English text */ +}; + +/* * struct PRErrorTable -- * * An error table, provided by a library. */ struct PRErrorTable { - struct PRErrorMessage { - const char * const name; /* Macro name for error */ - const char * const en_text; /* default english text */ - } const * msgs; /* Array of error information */ + const struct PRErrorMessage * msgs; /* Array of error information */ const char *name; /* Name of error table source */ PRErrorCode base; /* Error code for first error in table */ @@ -43,50 +50,49 @@ struct PRErrorTable { }; /* - * struct PRErrorPluginRock -- + * struct PRErrorCallbackPrivate -- * - * A rock, under which the localization plugin may store information - * that is private to itself. + * A private structure for the localization plugin */ -struct PRErrorPluginRock; +struct PRErrorCallbackPrivate; /* - * struct PRErrorPluginTableRock -- + * struct PRErrorCallbackTablePrivate -- * - * A rock, under which the localization plugin may store information, + * A data structure under which the localization plugin may store information, * associated with an error table, that is private to itself. */ -struct PRErrorPluginTableRock; +struct PRErrorCallbackTablePrivate; /* - * PRErrorPluginLookupFn -- + * PRErrorCallbackLookupFn -- * - * A function of PRErrorPluginLookupFn type is a localization + * A function of PRErrorCallbackLookupFn type is a localization * plugin callback which converts an error code into a description * in the requested language. The callback is provided the - * appropriate error table, rock, and table rock. The callback - * returns the appropriate UTF-8 encoded description, or NULL if no - * description can be found. + * appropriate error table, private data for the plugin and the table. + * The callback returns the appropriate UTF-8 encoded description, or NULL + * if no description can be found. */ typedef const char * -PRErrorPluginLookupFn(PRErrorCode code, PRLanguageCode language, +PRErrorCallbackLookupFn(PRErrorCode code, PRLanguageCode language, const struct PRErrorTable *table, - struct PRErrorPluginRock *rock, - struct PRErrorPluginTableRock *table_rock); + struct PRErrorCallbackPrivate *cb_private, + struct PRErrorCallbackTablePrivate *table_private); /* - * PRErrorPluginNewtableFn -- + * PRErrorCallbackNewtableFn -- * - * A function PRErrorPluginNewtableFn type is a localization plugin + * A function PRErrorCallbackNewtableFn type is a localization plugin * callback which is called once with each error table registered * with NSPR. The callback is provided with the error table and - * the plugin rock. The callback returns any table rock it wishes - * to associate with the error table. Does not need to be thread + * the plugin's private structure. The callback returns any table private + * data it wishes to associate with the error table. Does not need to be thread * safe. */ -typedef struct PRErrorPluginTableRock * -PRErrorPluginNewtableFn(const struct PRErrorTable *table, - struct PRErrorPluginRock *rock); +typedef struct PRErrorCallbackTablePrivate * +PRErrorCallbackNewtableFn(const struct PRErrorTable *table, + struct PRErrorCallbackPrivate *cb_private); /**********************************************************************/ /****************************** FUNCTIONS *****************************/ @@ -96,7 +102,9 @@ PRErrorPluginNewtableFn(const struct PRErrorTable *table, ** FUNCTION: PR_ErrorInstallTable ** DESCRIPTION: ** Registers an error table with NSPR. Must be done exactly once per -** table. +** table. Memory pointed to by `table' must remain valid for the life +** of the process. +** ** NOT THREAD SAFE! ** ***********************************************************************/ @@ -104,21 +112,23 @@ PR_EXTERN(PRErrorCode) PR_ErrorInstallTable(const struct PRErrorTable *table); /*********************************************************************** -** FUNCTION: PR_ErrorInstallPlugin +** FUNCTION: PR_ErrorInstallCallback ** DESCRIPTION: ** Registers an error localization plugin with NSPR. May be called ** at most one time. `languages' contains the language codes supported ** by this plugin. Languages 0 and 1 must be "i-default" and "en" ** respectively. `lookup' and `newtable' contain pointers to -** the plugin callback functions. `rock' contains any information +** the plugin callback functions. `cb_private' contains any information ** private to the plugin functions. +** ** NOT THREAD SAFE! +** ***********************************************************************/ -PR_EXTERN(void) PR_ErrorInstallPlugin(const char * const * languages, - PRErrorPluginLookupFn *lookup, - PRErrorPluginNewtableFn *newtable, - struct PRErrorPluginRock *rock); +PR_EXTERN(void) PR_ErrorInstallCallback(const char * const * languages, + PRErrorCallbackLookupFn *lookup, + PRErrorCallbackNewtableFn *newtable, + struct PRErrorCallbackPrivate *cb_private); PR_END_EXTERN_C -#endif /* prerrorplugin_h___ */ +#endif /* prerrorinstall_h___ */ diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h index b594d073..fa9a48c6 100644 --- a/pr/include/private/primpl.h +++ b/pr/include/private/primpl.h @@ -1482,6 +1482,7 @@ extern void _PR_InitAtomic(void); extern void _PR_InitCPUs(void); extern void _PR_InitDtoa(void); extern void _PR_InitMW(void); +extern void _PR_InitRWLocks(void); extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me); extern void _PR_CleanupThread(PRThread *thread); extern void _PR_CleanupTPD(void); diff --git a/pr/src/Makefile b/pr/src/Makefile index 82bfe77a..0e7c4e74 100644 --- a/pr/src/Makefile +++ b/pr/src/Makefile @@ -371,7 +371,7 @@ $(TINC): @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC) -$(OBJDIR)/prvrsion.$(OBJ_SUFFIX): $(TINC) +$(OBJDIR)/prvrsion.$(OBJ_SUFFIX): prvrsion.c $(TINC) ifeq ($(OS_ARCH), WINNT) ifdef XP_OS2_EMX $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) prvrsion.c diff --git a/pr/src/io/prfile.c b/pr/src/io/prfile.c index e9803866..03673755 100644 --- a/pr/src/io/prfile.c +++ b/pr/src/io/prfile.c @@ -463,37 +463,55 @@ PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf) PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd) { - PRStatus rv = PR_SUCCESS; + PRStatus status = PR_SUCCESS; + +#ifdef WINNT + if (!fd->secret->md.io_model_committed) { + PRInt32 rv; + rv = _md_Associate((HANDLE)fd->secret->md.osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } +#endif PR_Lock(_pr_flock_lock); if (fd->secret->lockCount == 0) { - rv = _PR_MD_LOCKFILE(fd->secret->md.osfd); - if (rv == PR_SUCCESS) + status = _PR_MD_LOCKFILE(fd->secret->md.osfd); + if (status == PR_SUCCESS) fd->secret->lockCount = 1; } else { fd->secret->lockCount++; } PR_Unlock(_pr_flock_lock); - return rv; + return status; } PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd) { - PRStatus rv = PR_SUCCESS; + PRStatus status = PR_SUCCESS; + +#ifdef WINNT + if (!fd->secret->md.io_model_committed) { + PRInt32 rv; + rv = _md_Associate((HANDLE)fd->secret->md.osfd); + PR_ASSERT(0 != rv); + fd->secret->md.io_model_committed = PR_TRUE; + } +#endif PR_Lock(_pr_flock_lock); if (fd->secret->lockCount == 0) { - rv = _PR_MD_TLOCKFILE(fd->secret->md.osfd); - PR_ASSERT(rv == PR_SUCCESS || fd->secret->lockCount == 0); - if (rv == PR_SUCCESS) + status = _PR_MD_TLOCKFILE(fd->secret->md.osfd); + PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0); + if (status == PR_SUCCESS) fd->secret->lockCount = 1; } else { fd->secret->lockCount++; } PR_Unlock(_pr_flock_lock); - return rv; + return status; } PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd) diff --git a/pr/src/misc/compile-et.pl b/pr/src/misc/compile-et.pl index 7bdc053c..7e0eeca9 100644 --- a/pr/src/misc/compile-et.pl +++ b/pr/src/misc/compile-et.pl @@ -100,7 +100,7 @@ while ($_ = <INPUT>) { } } -print H "extern void pr_init_error_table_", $table_name, "(void);\n"; +print H "extern void ", $table_name, "_InitializePRErrorTable","(void);\n"; printf H "#define ERROR_TABLE_BASE_%s (%dL)\n", $table_name, $table_base; print C "\t{0, 0}\n"; @@ -108,7 +108,7 @@ print C "};\n\n"; printf C "static const struct PRErrorTable et = { text, \"%s\", %dL, %d };\n", $base, $table_base, $table_item_count; print C "\n"; -print C "void pr_init_error_table_", $table_name, "() {\n"; +print C "void ", $table_name, "_InitializePRErrorTable", "() {\n"; print C " PR_ErrorInstallTable(&et);\n"; print C "}\n"; diff --git a/pr/src/misc/prerr.c b/pr/src/misc/prerr.c index 5e6046be..532bd55c 100644 --- a/pr/src/misc/prerr.c +++ b/pr/src/misc/prerr.c @@ -1,9 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + /* * * prerr.c * This file is automatically generated; please do not edit it. */ -#include "prerrorplugin.h" +#include "prerrorinstall.h" static const struct PRErrorMessage text[] = { {"PR_OUT_OF_MEMORY_ERROR", "Memory allocation attempt failed"}, {"PR_BAD_DESCRIPTOR_ERROR", "Invalid file descriptor"}, @@ -70,7 +88,7 @@ static const struct PRErrorMessage text[] = { {"PR_END_OF_FILE_ERROR", "Encountered end of file"}, {"PR_FILE_SEEK_ERROR", "Seek error"}, {"PR_FILE_IS_BUSY_ERROR", "The file is busy"}, - {"PR_RESERVED_ERROR", "Reserved Error Code"}, + {"PR_RESERVED_ERROR_5935", "Reserved Error Code -5935"}, {"PR_IN_PROGRESS_ERROR", "Operation is still in progress (probably a non-blocking connect)"}, {"PR_ALREADY_INITIATED_ERROR", "Operation has already been initiated (probably a non-blocking connect)"}, {"PR_GROUP_EMPTY_ERROR", "The wait group is empty"}, @@ -85,6 +103,6 @@ static const struct PRErrorMessage text[] = { static const struct PRErrorTable et = { text, "prerr", -6000L, 75 }; -void pr_init_error_table_nspr() { +void nspr_InitializePRErrorTable() { PR_ErrorInstallTable(&et); } diff --git a/pr/src/misc/prerr.et b/pr/src/misc/prerr.et index 4634c833..9ba441af 100644 --- a/pr/src/misc/prerr.et +++ b/pr/src/misc/prerr.et @@ -99,7 +99,7 @@ ec PR_NO_MORE_FILES_ERROR, "No more entries in the directory" ec PR_END_OF_FILE_ERROR, "Encountered end of file" ec PR_FILE_SEEK_ERROR, "Seek error" ec PR_FILE_IS_BUSY_ERROR, "The file is busy" -ec PR_RESERVED_ERROR, "Reserved Error Code" +ec PR_RESERVED_ERROR_5935, "Reserved Error Code -5935" ec PR_IN_PROGRESS_ERROR, "Operation is still in progress (probably a non-blocking connect)" ec PR_ALREADY_INITIATED_ERROR, diff --git a/pr/src/misc/prerrortable.c b/pr/src/misc/prerrortable.c index c589a952..e7439b0b 100644 --- a/pr/src/misc/prerrortable.c +++ b/pr/src/misc/prerrortable.c @@ -41,7 +41,7 @@ provided "as is" without express or implied warranty. #include <errno.h> #include "prmem.h" #include "prerror.h" -#include "prerrorplugin.h" +#include "prerrorinstall.h" #define ERRCODE_RANGE 8 /* # of bits to shift table number */ #define BITS_PER_CHAR 6 /* # bits to shift per character in name */ @@ -55,18 +55,18 @@ extern const int sys_nerr; struct PRErrorTableList { struct PRErrorTableList *next; const struct PRErrorTable *table; - struct PRErrorPluginTableRock *table_rock; + struct PRErrorCallbackTablePrivate *table_private; }; static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL; /* Supported languages */ static const char * default_languages[] = { "i-default", "en", 0 }; -static const char * const * plugin_languages = default_languages; +static const char * const * callback_languages = default_languages; -/* Plugin info */ -static struct PRErrorPluginRock *plugin_rock = 0; -static PRErrorPluginLookupFn *plugin_lookup = 0; -static PRErrorPluginNewtableFn *plugin_newtable = 0; +/* Callback info */ +static struct PRErrorCallbackPrivate *callback_private = 0; +static PRErrorCallbackLookupFn *callback_lookup = 0; +static PRErrorCallbackNewtableFn *callback_newtable = 0; static const char char_set[] = @@ -96,8 +96,6 @@ error_table_name (PRErrorCode num) return(buf); } - - PR_IMPLEMENT(const char *) PR_ErrorToString(PRErrorCode code, PRLanguageCode language) { @@ -117,9 +115,9 @@ PR_ErrorToString(PRErrorCode code, PRLanguageCode language) if (et->table->base <= code && et->table->base + et->table->n_msgs > code) { /* This is the right table */ - if (plugin_lookup) { - msg = plugin_lookup(code, language, et->table, - plugin_rock, et->table_rock); + if (callback_lookup) { + msg = callback_lookup(code, language, et->table, + callback_private, et->table_private); if (msg) return msg; } @@ -154,10 +152,26 @@ PR_ErrorToString(PRErrorCode code, PRLanguageCode language) return(buffer); } +PR_IMPLEMENT(const char *) +PR_ErrorToName(PRErrorCode code) +{ + struct PRErrorTableList *et; + + for (et = Table_List; et; et = et->next) { + if (et->table->base <= code && + et->table->base + et->table->n_msgs > code) { + /* This is the right table */ + return(et->table->msgs[code - et->table->base].name); + } + } + + return 0; +} + PR_IMPLEMENT(const char * const *) PR_ErrorLanguages(void) { - return plugin_languages; + return callback_languages; } PR_IMPLEMENT(PRErrorCode) @@ -170,10 +184,10 @@ PR_ErrorInstallTable(const struct PRErrorTable *table) if (!new_et) return errno; /* oops */ new_et->table = table; - if (plugin_newtable) { - new_et->table_rock = plugin_newtable(table, plugin_rock); + if (callback_newtable) { + new_et->table_private = callback_newtable(table, callback_private); } else { - new_et->table_rock = 0; + new_et->table_private = 0; } new_et->next = Table_List; Table_List = new_et; @@ -181,24 +195,24 @@ PR_ErrorInstallTable(const struct PRErrorTable *table) } PR_IMPLEMENT(void) -PR_ErrorInstallPlugin(const char * const * languages, - PRErrorPluginLookupFn *lookup, - PRErrorPluginNewtableFn *newtable, - struct PRErrorPluginRock *rock) +PR_ErrorInstallCallback(const char * const * languages, + PRErrorCallbackLookupFn *lookup, + PRErrorCallbackNewtableFn *newtable, + struct PRErrorCallbackPrivate *cb_private) { struct PRErrorTableList *et; assert(strcmp(languages[0], "i-default") == 0); assert(strcmp(languages[1], "en") == 0); - plugin_languages = languages; - plugin_lookup = lookup; - plugin_newtable = newtable; - plugin_rock = rock; + callback_languages = languages; + callback_lookup = lookup; + callback_newtable = newtable; + callback_private = cb_private; - if (plugin_newtable) { + if (callback_newtable) { for (et = Table_List; et; et = et->next) { - et->table_rock = plugin_newtable(et->table, plugin_rock); + et->table_private = callback_newtable(et->table, callback_private); } } } diff --git a/pr/src/misc/prinit.c b/pr/src/misc/prinit.c index 34a0e27e..01c30443 100644 --- a/pr/src/misc/prinit.c +++ b/pr/src/misc/prinit.c @@ -17,6 +17,7 @@ */ #include "primpl.h" +#include <ctype.h> #include <string.h> PRLogModuleInfo *_pr_clock_lm; @@ -73,11 +74,45 @@ PRBool _pr_initialized = PR_FALSE; PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion) { /* - ** This is the secret handshake algorithm. Right now it requires - ** an exact match. Later it should get more clever. + ** This is the secret handshake algorithm. + ** + ** This release (3.1) is backward compatible with + ** all the previous releases ("2.1 19980529", "3.0", + ** "3.0.x"). It is not compatible with future + ** releases or patches. So this release has a + ** simple version compatibility check algorithm. */ - if (!_pr_initialized) _PR_ImplicitInitialization(); - return ((0 == strcmp(importedVersion, PR_VERSION)) ? PR_TRUE : PR_FALSE); + int vmajor = 0, vminor = 0, vpatch = 0; + const char *ptr = importedVersion; + + while (isdigit(*ptr)) { + vmajor = 10 * vmajor + *ptr - '0'; + ptr++; + } + if (*ptr == '.') { + ptr++; + while (isdigit(*ptr)) { + vminor = 10 * vminor + *ptr - '0'; + ptr++; + } + if (*ptr == '.') { + ptr++; + while (isdigit(*ptr)) { + vpatch = 10 * vpatch + *ptr - '0'; + ptr++; + } + } + } + + if (vmajor > PR_VMAJOR) { + return PR_FALSE; + } else if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) { + return PR_FALSE; + } else if (vminor == PR_VMINOR && vpatch > PR_VPATCH) { + return PR_FALSE; + } else { + return PR_TRUE; + } } /* PR_VersionCheck */ @@ -149,8 +184,9 @@ static void _PR_InitStuff(void) _PR_InitCallOnce(); _PR_InitDtoa(); _PR_InitMW(); + _PR_InitRWLocks(); - pr_init_error_table_nspr(); + nspr_InitializePRErrorTable(); _PR_MD_FINAL_INIT(); } @@ -609,7 +645,6 @@ PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD( } ptr++; } - return NULL; } PR_IMPLEMENT(PRProcess*) PR_CreateProcess( diff --git a/pr/src/nspr.rc b/pr/src/nspr.rc index 570853fa..e31e9346 100644 --- a/pr/src/nspr.rc +++ b/pr/src/nspr.rc @@ -16,11 +16,36 @@ * Reserved. */ +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#ifndef WIN16 +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) +#endif //_WIN32 +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 + FILEVERSION 3,2,0,0 PRODUCTVERSION 3,1,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG @@ -32,6 +57,9 @@ VS_VERSION_INFO VERSIONINFO FILETYPE 0x1L FILESUBTYPE 0x0L +// end win16 +#endif + BEGIN BLOCK "StringFileInfo" BEGIN @@ -39,10 +67,15 @@ BEGIN BEGIN VALUE "CompanyName", "Netscape Communications Corporation\0" VALUE "FileDescription", "Netscape Portable Run Time\0" - VALUE "FileVersion", "1, 0, 0, 1\0" - VALUE "InternalName", "libnspr21\0" + VALUE "FileVersion", "3, 1, 0, 0\0" +#ifdef WINNT + VALUE "InternalName", "libnspr3\0" + VALUE "OriginalFilename", "libnspr3.dll\0" +#else + VALUE "InternalName", "nspr3\0" + VALUE "OriginalFilename", "nspr3.dll\0" +#endif VALUE "LegalCopyright", "Copyright © 1996\0" - VALUE "OriginalFilename", "libnspr21.dll\0" VALUE "ProductName", "Netscape Communication Corporation NSPR20\0" VALUE "ProductVersion", "3, 1, 0, 0\0" END @@ -53,3 +86,46 @@ BEGIN END END +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c index 0bccc779..0f6206b1 100644 --- a/pr/src/pthreads/ptthread.c +++ b/pr/src/pthreads/ptthread.c @@ -309,10 +309,35 @@ static PRThread* _PR_CreateThread( thred->priority = priority; if (PR_UNJOINABLE_THREAD == state) thred->state |= PT_THREAD_DETACHED; + + if (PR_LOCAL_THREAD == scope) + scope = PR_GLOBAL_THREAD; + + if (PR_GLOBAL_BOUND_THREAD == scope) { + /* + * should a Posix feature test be used here? + */ +#ifdef PTHREAD_SCOPE_SYSTEM + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM); + if (rv) { + /* + * system scope not supported + */ + scope = PR_GLOBAL_THREAD; + /* + * reset scope + */ + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS); + PR_ASSERT(0 == rv); + } +#endif + } if (PR_GLOBAL_THREAD == scope) thred->state |= PT_THREAD_GLOBAL; - if (PR_GLOBAL_BOUND_THREAD == scope) + else if (PR_GLOBAL_BOUND_THREAD == scope) thred->state |= (PT_THREAD_GLOBAL | PT_THREAD_BOUND); + else /* force it global */ + thred->state |= PT_THREAD_GLOBAL; if (PR_SYSTEM_THREAD == type) thred->state |= PT_THREAD_SYSTEM; @@ -341,14 +366,6 @@ static PRThread* _PR_CreateThread( else pt_book.user += 1; PR_Unlock(pt_book.ml); - if (thred->state & PT_THREAD_BOUND) { - /* - * should a Posix feature test be used here? - */ -#ifdef PTHREAD_SCOPE_SYSTEM - rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM); -#endif - } /* * We pass a pointer to a local copy (instead of thred->id) * to pthread_create() because who knows what wacky things @@ -359,6 +376,17 @@ static PRThread* _PR_CreateThread( #if !defined(_PR_DCETHREADS) if (EPERM == rv) { +#if defined(IRIX) + if (PR_GLOBAL_BOUND_THREAD == scope) { + /* + * SCOPE_SYSTEM requires appropriate privilege + * reset to process scope and try again + */ + rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS); + PR_ASSERT(0 == rv); + thred->state &= ~PT_THREAD_BOUND; + } +#else /* Remember that we don't have thread scheduling privilege. */ pt_schedpriv = EPERM; PR_LOG(_pr_thread_lm, PR_LOG_MIN, @@ -368,6 +396,7 @@ static PRThread* _PR_CreateThread( rv = pthread_attr_setinheritsched(&tattr, PTHREAD_INHERIT_SCHED); PR_ASSERT(0 == rv); #endif +#endif /* IRIX */ rv = PTHREAD_CREATE(&id, tattr, _pt_root, thred); } #endif diff --git a/pr/src/resource.h b/pr/src/resource.h index 5834cf3f..8350f5a9 100644 --- a/pr/src/resource.h +++ b/pr/src/resource.h @@ -16,6 +16,18 @@ * Reserved. */ -#if 0 -There are no resources for NSPR. +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by nspr.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif #endif diff --git a/pr/src/threads/prrwlock.c b/pr/src/threads/prrwlock.c index ec14e788..fde727e3 100644 --- a/pr/src/threads/prrwlock.c +++ b/pr/src/threads/prrwlock.c @@ -16,17 +16,46 @@ * Reserved. */ -#include "nspr.h" +#include "primpl.h" #include <string.h> +#if defined(HPUX) && defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) + +#include <pthread.h> +#define HAVE_UNIX98_RWLOCK +#define RWLOCK_T pthread_rwlock_t +#define RWLOCK_INIT(lock) pthread_rwlock_init(lock, NULL) +#define RWLOCK_DESTROY(lock) pthread_rwlock_destroy(lock) +#define RWLOCK_RDLOCK(lock) pthread_rwlock_rdlock(lock) +#define RWLOCK_WRLOCK(lock) pthread_rwlock_wrlock(lock) +#define RWLOCK_UNLOCK(lock) pthread_rwlock_unlock(lock) + +#elif defined(SOLARIS) && (defined(_PR_PTHREADS) \ + || defined(_PR_GLOBAL_THREADS_ONLY)) + +#include <synch.h> +#define HAVE_UI_RWLOCK +#define RWLOCK_T rwlock_t +#define RWLOCK_INIT(lock) rwlock_init(lock, USYNC_THREAD, NULL) +#define RWLOCK_DESTROY(lock) rwlock_destroy(lock) +#define RWLOCK_RDLOCK(lock) rw_rdlock(lock) +#define RWLOCK_WRLOCK(lock) rw_wrlock(lock) +#define RWLOCK_UNLOCK(lock) rw_unlock(lock) + +#endif + /* * Reader-writer lock */ struct PRRWLock { - PRLock *rw_lock; char *rw_name; /* lock name */ PRUint32 rw_rank; /* rank of the lock */ + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + RWLOCK_T rw_lock; +#else + PRLock *rw_lock; PRInt32 rw_lock_cnt; /* == 0, if unlocked */ /* == -1, if write-locked */ /* > 0 , # of read locks */ @@ -34,7 +63,10 @@ struct PRRWLock { PRUint32 rw_writer_cnt; /* number of waiting writers */ PRCondVar *rw_reader_waitq; /* cvar for readers */ PRCondVar *rw_writer_waitq; /* cvar for writers */ +#ifdef DEBUG PRThread *rw_owner; /* lock owner for write-lock */ +#endif +#endif }; #ifdef DEBUG @@ -45,8 +77,7 @@ struct PRRWLock { #ifdef _PR_RWLOCK_RANK_ORDER_DEBUG -static PRUintn pr_thread_rwlock_initialized; -static PRUintn pr_thread_rwlock; /* TPD key for lock stack */ +static PRUintn pr_thread_rwlock_key; /* TPD key for lock stack */ static PRUintn pr_thread_rwlock_alloc_failed; #define _PR_RWLOCK_RANK_ORDER_LIMIT 10 @@ -79,35 +110,20 @@ PR_IMPLEMENT(PRRWLock *) PR_NewRWLock(PRUint32 lock_rank, const char *lock_name) { PRRWLock *rwlock; +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + int err; +#endif + + if (!_pr_initialized) _PR_ImplicitInitialization(); rwlock = PR_NEWZAP(PRRWLock); if (rwlock == NULL) return NULL; - - rwlock->rw_lock = PR_NewLock(); - if (rwlock->rw_lock == NULL) { - PR_DELETE(rwlock); - return(NULL); - } - rwlock->rw_reader_waitq = PR_NewCondVar(rwlock->rw_lock); - if (rwlock->rw_reader_waitq == NULL) { - PR_DestroyLock(rwlock->rw_lock); - PR_DELETE(rwlock); - return(NULL); - } - rwlock->rw_writer_waitq = PR_NewCondVar(rwlock->rw_lock); - if (rwlock->rw_writer_waitq == NULL) { - PR_DestroyCondVar(rwlock->rw_reader_waitq); - PR_DestroyLock(rwlock->rw_lock); - PR_DELETE(rwlock); - return(NULL); - } + + rwlock->rw_rank = lock_rank; if (lock_name != NULL) { rwlock->rw_name = (char*) PR_Malloc(strlen(lock_name) + 1); if (rwlock->rw_name == NULL) { - PR_DestroyCondVar(rwlock->rw_reader_waitq); - PR_DestroyCondVar(rwlock->rw_writer_waitq); - PR_DestroyLock(rwlock->rw_lock); PR_DELETE(rwlock); return(NULL); } @@ -115,12 +131,45 @@ PR_NewRWLock(PRUint32 lock_rank, const char *lock_name) } else { rwlock->rw_name = NULL; } - rwlock->rw_rank = lock_rank; + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_INIT(&rwlock->rw_lock); + if (err != 0) { + PR_SetError(PR_UNKNOWN_ERROR, err); + PR_Free(rwlock->rw_name); + PR_DELETE(rwlock); + return NULL; + } + return rwlock; +#else + rwlock->rw_lock = PR_NewLock(); + if (rwlock->rw_lock == NULL) { + goto failed; + } + rwlock->rw_reader_waitq = PR_NewCondVar(rwlock->rw_lock); + if (rwlock->rw_reader_waitq == NULL) { + goto failed; + } + rwlock->rw_writer_waitq = PR_NewCondVar(rwlock->rw_lock); + if (rwlock->rw_writer_waitq == NULL) { + goto failed; + } rwlock->rw_reader_cnt = 0; rwlock->rw_writer_cnt = 0; rwlock->rw_lock_cnt = 0; + return rwlock; - return rwlock; +failed: + if (rwlock->rw_reader_waitq != NULL) { + PR_DestroyCondVar(rwlock->rw_reader_waitq); + } + if (rwlock->rw_lock != NULL) { + PR_DestroyLock(rwlock->rw_lock); + } + PR_Free(rwlock->rw_name); + PR_DELETE(rwlock); + return NULL; +#endif } /* @@ -129,10 +178,16 @@ PR_NewRWLock(PRUint32 lock_rank, const char *lock_name) PR_IMPLEMENT(void) PR_DestroyRWLock(PRRWLock *rwlock) { +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + int err; + err = RWLOCK_DESTROY(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else PR_ASSERT(rwlock->rw_reader_cnt == 0); PR_DestroyCondVar(rwlock->rw_reader_waitq); PR_DestroyCondVar(rwlock->rw_writer_waitq); PR_DestroyLock(rwlock->rw_lock); +#endif if (rwlock->rw_name != NULL) PR_Free(rwlock->rw_name); PR_DELETE(rwlock); @@ -144,10 +199,14 @@ PR_DestroyRWLock(PRRWLock *rwlock) PR_IMPLEMENT(void) PR_RWLock_Rlock(PRRWLock *rwlock) { +#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG PRThread *me = PR_GetCurrentThread(); +#endif +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) +int err; +#endif #ifdef _PR_RWLOCK_RANK_ORDER_DEBUG - /* * assert that rank ordering is not violated; the rank of 'rwlock' should * be equal to or greater than the highest rank of all the locks held by @@ -156,6 +215,11 @@ PRThread *me = PR_GetCurrentThread(); PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || (rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK(me))); #endif + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_RDLOCK(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else PR_Lock(rwlock->rw_lock); /* * wait if write-locked or if a writer is waiting; preference for writers @@ -172,6 +236,7 @@ PRThread *me = PR_GetCurrentThread(); rwlock->rw_lock_cnt++; PR_Unlock(rwlock->rw_lock); +#endif #ifdef _PR_RWLOCK_RANK_ORDER_DEBUG /* @@ -188,7 +253,12 @@ PR_IMPLEMENT(void) PR_RWLock_Wlock(PRRWLock *rwlock) { PRInt32 lock_acquired = 0; +#if defined(DEBUG) || defined(_PR_RWLOCK_RANK_ORDER_DEBUG) PRThread *me = PR_GetCurrentThread(); +#endif +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) +int err; +#endif #ifdef _PR_RWLOCK_RANK_ORDER_DEBUG /* @@ -199,6 +269,11 @@ PRThread *me = PR_GetCurrentThread(); PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || (rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK(me))); #endif + +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_WRLOCK(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else PR_Lock(rwlock->rw_lock); /* * wait if read locked @@ -214,8 +289,11 @@ PRThread *me = PR_GetCurrentThread(); rwlock->rw_lock_cnt--; PR_ASSERT(rwlock->rw_lock_cnt == -1); PR_ASSERT(me != NULL); +#ifdef DEBUG rwlock->rw_owner = me; +#endif PR_Unlock(rwlock->rw_lock); +#endif #ifdef _PR_RWLOCK_RANK_ORDER_DEBUG /* @@ -231,8 +309,17 @@ PRThread *me = PR_GetCurrentThread(); PR_IMPLEMENT(void) PR_RWLock_Unlock(PRRWLock *rwlock) { +#if defined(DEBUG) || defined(_PR_RWLOCK_RANK_ORDER_DEBUG) PRThread *me = PR_GetCurrentThread(); +#endif +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) +int err; +#endif +#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK) + err = RWLOCK_UNLOCK(&rwlock->rw_lock); + PR_ASSERT(err == 0); +#else PR_Lock(rwlock->rw_lock); /* * lock must be read or write-locked @@ -252,13 +339,13 @@ PRThread *me = PR_GetCurrentThread(); PR_NotifyCondVar(rwlock->rw_writer_waitq); } } else { - PRThread *me = PR_GetCurrentThread(); - PR_ASSERT(rwlock->rw_lock_cnt == -1); rwlock->rw_lock_cnt = 0; +#ifdef DEBUG PR_ASSERT(rwlock->rw_owner == me); rwlock->rw_owner = NULL; +#endif /* * wakeup a writer, if present; preference for writers */ @@ -271,6 +358,7 @@ PRThread *me = PR_GetCurrentThread(); PR_NotifyAllCondVar(rwlock->rw_reader_waitq); } PR_Unlock(rwlock->rw_lock); +#endif #ifdef _PR_RWLOCK_RANK_ORDER_DEBUG /* @@ -281,7 +369,23 @@ PRThread *me = PR_GetCurrentThread(); return; } -#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG +#ifndef _PR_RWLOCK_RANK_ORDER_DEBUG + +void _PR_InitRWLocks(void) { } + +#else + +void _PR_InitRWLocks(void) +{ + /* + * allocated thread-private-data index for rwlock list + */ + if (PR_NewThreadPrivateIndex(&pr_thread_rwlock_key, + _PR_RELEASE_LOCK_STACK) == PR_FAILURE) { + pr_thread_rwlock_alloc_failed = 1; + return; + } +} /* * _PR_SET_THREAD_RWLOCK_RANK @@ -297,30 +401,13 @@ thread_rwlock_stack *lock_stack; PRStatus rv; /* - * allocated thread-private-data for rwlock list, if not already allocated - */ - if (!pr_thread_rwlock_initialized) { - /* - * allocate tpd, only if not failed already - */ - if (!pr_thread_rwlock_alloc_failed) { - if (PR_NewThreadPrivateIndex(&pr_thread_rwlock, - _PR_RELEASE_LOCK_STACK) - == PR_FAILURE) { - pr_thread_rwlock_alloc_failed = 1; - return; - } - } else - return; - } - /* * allocate a lock stack */ - if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock)) == NULL) { + if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) { lock_stack = (thread_rwlock_stack *) PR_CALLOC(1 * sizeof(thread_rwlock_stack)); if (lock_stack) { - rv = PR_SetThreadPrivate(pr_thread_rwlock, lock_stack); + rv = PR_SetThreadPrivate(pr_thread_rwlock_key, lock_stack); if (rv == PR_FAILURE) { PR_DELETE(lock_stack); pr_thread_rwlock_alloc_failed = 1; @@ -338,7 +425,6 @@ PRStatus rv; if (lock_stack->trs_index < _PR_RWLOCK_RANK_ORDER_LIMIT) lock_stack->trs_stack[lock_stack->trs_index++] = rwlock; } - pr_thread_rwlock_initialized = 1; } static void @@ -360,14 +446,10 @@ _PR_GET_THREAD_RWLOCK_RANK(PRThread *me) { thread_rwlock_stack *lock_stack; - if (pr_thread_rwlock_initialized) { - if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock)) == NULL) - return (PR_RWLOCK_RANK_NONE); - else - return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank); - - } else - return (PR_RWLOCK_RANK_NONE); + if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) + return (PR_RWLOCK_RANK_NONE); + else + return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank); } /* @@ -383,10 +465,7 @@ _PR_UNSET_THREAD_RWLOCK_RANK(PRThread *me, PRRWLock *rwlock) thread_rwlock_stack *lock_stack; int new_index = 0, index, done = 0; - if (!pr_thread_rwlock_initialized) - return; - - lock_stack = PR_GetThreadPrivate(pr_thread_rwlock); + lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key); PR_ASSERT(lock_stack != NULL); diff --git a/pr/tests/Makefile b/pr/tests/Makefile index d5e3eab3..863cca8d 100644 --- a/pr/tests/Makefile +++ b/pr/tests/Makefile @@ -51,6 +51,7 @@ CSRCS = \ dceemu.c \ dlltest.c \ dtoa.c \ + errcodes.c \ exit.c \ fileio.c \ foreign.c \ @@ -138,6 +139,7 @@ CSRCS = \ tmoacc.c \ tmocon.c \ tpd.c \ + vercheck.c \ version.c \ udpsrv.c \ writev.c \ @@ -472,6 +474,10 @@ $(OBJDIR)/foreign: $(OBJDIR)/foreign.o $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ $(OBJDIR)/provider: $(OBJDIR)/provider.o $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +$(OBJDIR)/socket: $(OBJDIR)/socket.o + $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ +$(OBJDIR)/testfile: $(OBJDIR)/testfile.o + $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@ endif # diff --git a/pr/tests/errcodes.c b/pr/tests/errcodes.c new file mode 100644 index 00000000..3fdf777b --- /dev/null +++ b/pr/tests/errcodes.c @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/*********************************************************************** +** +** Name: errcodes.c +** +** Description: print nspr error codes +** +*/ +#include "prerror.h" +#include "plgetopt.h" + +#include <stdio.h> + +static int _debug_on = 0; + +struct errinfo { + PRErrorCode errcode; + char *errname; +}; + +struct errinfo errcodes[] = { +{PR_OUT_OF_MEMORY_ERROR, "PR_OUT_OF_MEMORY_ERROR"}, +{PR_BAD_DESCRIPTOR_ERROR, "PR_BAD_DESCRIPTOR_ERROR"}, +{PR_WOULD_BLOCK_ERROR, "PR_WOULD_BLOCK_ERROR"}, +{PR_ACCESS_FAULT_ERROR, "PR_ACCESS_FAULT_ERROR"}, +{PR_INVALID_METHOD_ERROR, "PR_INVALID_METHOD_ERROR"}, +{PR_ILLEGAL_ACCESS_ERROR, "PR_ILLEGAL_ACCESS_ERROR"}, +{PR_UNKNOWN_ERROR, "PR_UNKNOWN_ERROR"}, +{PR_PENDING_INTERRUPT_ERROR, "PR_PENDING_INTERRUPT_ERROR"}, +{PR_NOT_IMPLEMENTED_ERROR, "PR_NOT_IMPLEMENTED_ERROR"}, +{PR_IO_ERROR, "PR_IO_ERROR"}, +{PR_IO_TIMEOUT_ERROR, "PR_IO_TIMEOUT_ERROR"}, +{PR_IO_PENDING_ERROR, "PR_IO_PENDING_ERROR"}, +{PR_DIRECTORY_OPEN_ERROR, "PR_DIRECTORY_OPEN_ERROR"}, +{PR_INVALID_ARGUMENT_ERROR, "PR_INVALID_ARGUMENT_ERROR"}, +{PR_ADDRESS_NOT_AVAILABLE_ERROR, "PR_ADDRESS_NOT_AVAILABLE_ERROR"}, +{PR_ADDRESS_NOT_SUPPORTED_ERROR, "PR_ADDRESS_NOT_SUPPORTED_ERROR"}, +{PR_IS_CONNECTED_ERROR, "PR_IS_CONNECTED_ERROR"}, +{PR_BAD_ADDRESS_ERROR, "PR_BAD_ADDRESS_ERROR"}, +{PR_ADDRESS_IN_USE_ERROR, "PR_ADDRESS_IN_USE_ERROR"}, +{PR_CONNECT_REFUSED_ERROR, "PR_CONNECT_REFUSED_ERROR"}, +{PR_NETWORK_UNREACHABLE_ERROR, "PR_NETWORK_UNREACHABLE_ERROR"}, +{PR_CONNECT_TIMEOUT_ERROR, "PR_CONNECT_TIMEOUT_ERROR"}, +{PR_NOT_CONNECTED_ERROR, "PR_NOT_CONNECTED_ERROR"}, +{PR_LOAD_LIBRARY_ERROR, "PR_LOAD_LIBRARY_ERROR"}, +{PR_UNLOAD_LIBRARY_ERROR, "PR_UNLOAD_LIBRARY_ERROR"}, +{PR_FIND_SYMBOL_ERROR, "PR_FIND_SYMBOL_ERROR"}, +{PR_INSUFFICIENT_RESOURCES_ERROR, "PR_INSUFFICIENT_RESOURCES_ERROR"}, +{PR_DIRECTORY_LOOKUP_ERROR, "PR_DIRECTORY_LOOKUP_ERROR"}, +{PR_TPD_RANGE_ERROR, "PR_TPD_RANGE_ERROR"}, +{PR_PROC_DESC_TABLE_FULL_ERROR, "PR_PROC_DESC_TABLE_FULL_ERROR"}, +{PR_SYS_DESC_TABLE_FULL_ERROR, "PR_SYS_DESC_TABLE_FULL_ERROR"}, +{PR_NOT_SOCKET_ERROR, "PR_NOT_SOCKET_ERROR"}, +{PR_NOT_TCP_SOCKET_ERROR, "PR_NOT_TCP_SOCKET_ERROR"}, +{PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "PR_SOCKET_ADDRESS_IS_BOUND_ERROR"}, +{PR_NO_ACCESS_RIGHTS_ERROR, "PR_NO_ACCESS_RIGHTS_ERROR"}, +{PR_OPERATION_NOT_SUPPORTED_ERROR, "PR_OPERATION_NOT_SUPPORTED_ERROR"}, +{PR_PROTOCOL_NOT_SUPPORTED_ERROR, "PR_PROTOCOL_NOT_SUPPORTED_ERROR"}, +{PR_REMOTE_FILE_ERROR, "PR_REMOTE_FILE_ERROR"}, +{PR_BUFFER_OVERFLOW_ERROR, "PR_BUFFER_OVERFLOW_ERROR"}, +{PR_CONNECT_RESET_ERROR, "PR_CONNECT_RESET_ERROR"}, +{PR_RANGE_ERROR, "PR_RANGE_ERROR"}, +{PR_DEADLOCK_ERROR, "PR_DEADLOCK_ERROR"}, +{PR_FILE_IS_LOCKED_ERROR, "PR_FILE_IS_LOCKED_ERROR"}, +{PR_FILE_TOO_BIG_ERROR, "PR_FILE_TOO_BIG_ERROR"}, +{PR_NO_DEVICE_SPACE_ERROR, "PR_NO_DEVICE_SPACE_ERROR"}, +{PR_PIPE_ERROR, "PR_PIPE_ERROR"}, +{PR_NO_SEEK_DEVICE_ERROR, "PR_NO_SEEK_DEVICE_ERROR"}, +{PR_IS_DIRECTORY_ERROR, "PR_IS_DIRECTORY_ERROR"}, +{PR_LOOP_ERROR, "PR_LOOP_ERROR"}, +{PR_NAME_TOO_LONG_ERROR, "PR_NAME_TOO_LONG_ERROR"}, +{PR_FILE_NOT_FOUND_ERROR, "PR_FILE_NOT_FOUND_ERROR"}, +{PR_NOT_DIRECTORY_ERROR, "PR_NOT_DIRECTORY_ERROR"}, +{PR_READ_ONLY_FILESYSTEM_ERROR, "PR_READ_ONLY_FILESYSTEM_ERROR"}, +{PR_DIRECTORY_NOT_EMPTY_ERROR, "PR_DIRECTORY_NOT_EMPTY_ERROR"}, +{PR_FILESYSTEM_MOUNTED_ERROR, "PR_FILESYSTEM_MOUNTED_ERROR"}, +{PR_NOT_SAME_DEVICE_ERROR, "PR_NOT_SAME_DEVICE_ERROR"}, +{PR_DIRECTORY_CORRUPTED_ERROR, "PR_DIRECTORY_CORRUPTED_ERROR"}, +{PR_FILE_EXISTS_ERROR, "PR_FILE_EXISTS_ERROR"}, +{PR_MAX_DIRECTORY_ENTRIES_ERROR, "PR_MAX_DIRECTORY_ENTRIES_ERROR"}, +{PR_INVALID_DEVICE_STATE_ERROR, "PR_INVALID_DEVICE_STATE_ERROR"}, +{PR_DEVICE_IS_LOCKED_ERROR, "PR_DEVICE_IS_LOCKED_ERROR"}, +{PR_NO_MORE_FILES_ERROR, "PR_NO_MORE_FILES_ERROR"}, +{PR_END_OF_FILE_ERROR, "PR_END_OF_FILE_ERROR"}, +{PR_FILE_SEEK_ERROR, "PR_FILE_SEEK_ERROR"}, +{PR_FILE_IS_BUSY_ERROR, "PR_FILE_IS_BUSY_ERROR"}, +{PR_IN_PROGRESS_ERROR, "PR_IN_PROGRESS_ERROR"}, +{PR_ALREADY_INITIATED_ERROR, "PR_ALREADY_INITIATED_ERROR"}, +{PR_GROUP_EMPTY_ERROR, "PR_GROUP_EMPTY_ERROR"}, +{PR_INVALID_STATE_ERROR, "PR_INVALID_STATE_ERROR"}, +{PR_NETWORK_DOWN_ERROR, "PR_NETWORK_DOWN_ERROR"}, +{PR_SOCKET_SHUTDOWN_ERROR, "PR_SOCKET_SHUTDOWN_ERROR"}, +{PR_CONNECT_ABORTED_ERROR, "PR_CONNECT_ABORTED_ERROR"}, +{PR_HOST_UNREACHABLE_ERROR, "PR_HOST_UNREACHABLE_ERROR"} +}; + +int +main(int argc, char **argv) +{ + + int count, errnum; + + /* + * -d debug mode + */ + + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "d"); + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug mode */ + _debug_on = 1; + break; + default: + break; + } + } + PL_DestroyOptState(opt); + + count = sizeof(errcodes)/sizeof(errcodes[0]); + printf("\nNumber of error codes = %d\n\n",count); + for (errnum = 0; errnum < count; errnum++) { + printf("%-40s = %d\n",errcodes[errnum].errname, + errcodes[errnum].errcode); + } + + return 0; +} diff --git a/pr/tests/rwlocktest.c b/pr/tests/rwlocktest.c index 7ee30320..3ca58732 100644 --- a/pr/tests/rwlocktest.c +++ b/pr/tests/rwlocktest.c @@ -36,14 +36,13 @@ static void check_array(void); typedef struct thread_args { PRRWLock *rwlock; PRInt32 loop_cnt; - void *data; } thread_args; PRFileDesc *output; PRFileDesc *errhandle; #define DEFAULT_THREAD_CNT 4 -#define DEFAULT_DATA_CNT 100 +#define DEFAULT_LOOP_CNT 100 #define TEST_ARRAY_SIZE 100 PRIntn main(PRIntn argc, char **argv) @@ -53,13 +52,13 @@ PRIntn main(PRIntn argc, char **argv) PRInt32 i; PRInt32 thread_cnt = DEFAULT_THREAD_CNT; - PRInt32 data_cnt = DEFAULT_DATA_CNT; + PRInt32 loop_cnt = DEFAULT_LOOP_CNT; PRThread **threads; thread_args *params; PRRWLock *rwlock1; PLOptStatus os; - PLOptState *opt = PL_CreateOptState(argc, argv, "dt:"); + PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { @@ -72,8 +71,8 @@ PRIntn main(PRIntn argc, char **argv) case 't': /* thread count */ thread_cnt = atoi(opt->value); break; - case 'c': /* data count */ - data_cnt = atoi(opt->value); + case 'c': /* loop count */ + loop_cnt = atoi(opt->value); break; default: break; @@ -99,12 +98,9 @@ PRIntn main(PRIntn argc, char **argv) /* * allocate and initialize data arrays */ - array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE - * TEST_ARRAY_SIZE); - array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE - * TEST_ARRAY_SIZE); - array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE - * TEST_ARRAY_SIZE); + array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); + array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); + array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE); cnt = 0; for (i=0; i < TEST_ARRAY_SIZE;i++) { array_A[i] = cnt++; @@ -113,14 +109,13 @@ PRIntn main(PRIntn argc, char **argv) } if (_debug_on) - PR_fprintf(output,"%s: thread_cnt = %d data_cnt = %d\n", argv[0], - thread_cnt, data_cnt); + PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0], + thread_cnt, loop_cnt); for(cnt = 0; cnt < thread_cnt; cnt++) { PRThreadScope scope; params[cnt].rwlock = rwlock1; - params[cnt].data = NULL; - params[cnt].loop_cnt = data_cnt; + params[cnt].loop_cnt = loop_cnt; /* * create LOCAL and GLOBAL threads alternately @@ -162,6 +157,7 @@ PRIntn main(PRIntn argc, char **argv) PR_DestroyRWLock(rwlock1); + printf("PASS\n"); return 0; } diff --git a/pr/tests/socket.c b/pr/tests/socket.c index 47c134d2..1a08a02c 100644 --- a/pr/tests/socket.c +++ b/pr/tests/socket.c @@ -34,6 +34,13 @@ #ifdef XP_UNIX #include <sys/mman.h> #endif +#if defined(_PR_PTHREADS) +#include <pthread.h> +#endif + +#ifdef WINNT +#include <process.h> +#endif static int _debug_on = 0; @@ -244,6 +251,62 @@ exit: } } +PRThread* create_new_thread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, PRInt32 index) +{ +PRInt32 native_thread = 0; + + PR_ASSERT(state == PR_UNJOINABLE_THREAD); +#if defined(_PR_PTHREADS) || defined(WINNT) + switch(index % 4) { + case 0: + scope = (PR_LOCAL_THREAD); + break; + case 1: + scope = (PR_GLOBAL_THREAD); + break; + case 2: + scope = (PR_GLOBAL_BOUND_THREAD); + break; + case 3: + native_thread = 1; + break; + default: + PR_ASSERT(!"Invalid scope"); + break; + } + if (native_thread) { +#ifdef _PR_PTHREADS + pthread_t tid; + if (!pthread_create(&tid, NULL, start, arg)) + return((PRThread *) tid); + else + return (NULL); +#else + HANDLE thandle; + + thandle = (HANDLE) _beginthreadex( + NULL, + stackSize, + (unsigned (__stdcall *)(void *))start, + arg, + 0, + NULL); + return((PRThread *) thandle); +#endif + } else { + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); + } +#else + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); +#endif +} + /* * TCP Server * Server Thread @@ -330,12 +393,12 @@ TCP_Server(void *arg) scp->sockfd = newsockfd; scp->datalen = sp->datalen; - t = PR_CreateThread(PR_USER_THREAD, + t = create_new_thread(PR_USER_THREAD, Serve_Client, (void *)scp, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, - 0); + 0, i); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); failed_already=1; @@ -729,7 +792,6 @@ TCP_Socket_Client_Server_Test(void) { int i; PRThread *t; - PRThreadScope scope; PRSemaphore *server_sem; Server_Param *sparamp; Client_Param *cparamp; @@ -801,19 +863,12 @@ TCP_Socket_Client_Server_Test(void) cparamp->exit_counter = &thread_count; cparamp->datalen = datalen; for (i = 0; i < num_tcp_clients; i++) { - /* - * Every other thread is a LOCAL/GLOBAL thread - */ - if (i & 1) - scope = PR_LOCAL_THREAD; - else - scope = PR_GLOBAL_THREAD; - t = PR_CreateThread(PR_USER_THREAD, + t = create_new_thread(PR_USER_THREAD, TCP_Client, (void *) cparamp, PR_PRIORITY_NORMAL, - scope, + PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, - 0); + 0, i); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); failed_already=1; @@ -1134,7 +1189,6 @@ TransmitFile_Server(void *arg) PRFileDesc *sockfd = NULL, *newsockfd; PRNetAddr netaddr; PRInt32 i; - PRThreadScope scope; t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *)); if (t == NULL) { @@ -1218,17 +1272,10 @@ TransmitFile_Server(void *arg) scp->sockfd = newsockfd; scp->datalen = sp->datalen; - /* - * create LOCAL and GLOBAL threads alternately - */ - if (i & 1) - scope = PR_LOCAL_THREAD; - else - scope = PR_GLOBAL_THREAD; t[i] = PR_CreateThread(PR_USER_THREAD, Serve_TransmitFile_Client, (void *)scp, PR_PRIORITY_NORMAL, - scope, + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); if (t[i] == NULL) { @@ -1277,7 +1324,6 @@ Socket_Misc_Test(void) { PRIntn i, rv = 0, bytes, count, len; PRThread *t; - PRThreadScope scope; PRSemaphore *server_sem; Server_Param *sparamp; Client_Param *cparamp; @@ -1484,19 +1530,12 @@ Socket_Misc_Test(void) cparamp->exit_counter = &thread_count; cparamp->datalen = datalen; for (i = 0; i < num_transmitfile_clients; i++) { - /* - * Every other thread is a LOCAL/GLOBAL thread - */ - if (i & 1) - scope = PR_GLOBAL_THREAD; - else - scope = PR_LOCAL_THREAD; - t = PR_CreateThread(PR_USER_THREAD, + t = create_new_thread(PR_USER_THREAD, TransmitFile_Client, (void *) cparamp, PR_PRIORITY_NORMAL, - scope, + PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, - 0); + 0, i); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); rv = -1; diff --git a/pr/tests/testfile.c b/pr/tests/testfile.c index b125e219..1e75d0f2 100644 --- a/pr/tests/testfile.c +++ b/pr/tests/testfile.c @@ -24,6 +24,10 @@ #include <string.h> #ifdef WIN32 #include <windows.h> +#include <process.h> +#endif +#if defined(_PR_PTHREADS) +#include <pthread.h> #endif #if defined(XP_OS2) @@ -61,7 +65,8 @@ int thread_count; #define BUF_DATA_SIZE 256 * 1024 #endif -#define NUM_RDWR_THREADS 10 +#define NUM_RDWR_THREADS 10 +#define NUM_DIRTEST_THREADS 4 #define CHUNK_SIZE 512 typedef struct buffer { @@ -90,6 +95,68 @@ char *HIDDEN_FILE_NAME = ".hidden_pr_testfile"; #endif buffer *in_buf, *out_buf; char pathname[256], renamename[256]; +#define TMPDIR_LEN 64 +char testdir[TMPDIR_LEN]; +static PRInt32 PR_CALLBACK DirTest(void *argunused); +PRInt32 dirtest_failed = 0; + +PRThread* create_new_thread(PRThreadType type, + void (*start)(void *arg), + void *arg, + PRThreadPriority priority, + PRThreadScope scope, + PRThreadState state, + PRUint32 stackSize, PRInt32 index) +{ +PRInt32 native_thread = 0; + + PR_ASSERT(state == PR_UNJOINABLE_THREAD); +#if defined(_PR_PTHREADS) || defined(WINNT) + switch(index % 4) { + case 0: + scope = (PR_LOCAL_THREAD); + break; + case 1: + scope = (PR_GLOBAL_THREAD); + break; + case 2: + scope = (PR_GLOBAL_BOUND_THREAD); + break; + case 3: + native_thread = 1; + break; + default: + PR_ASSERT(!"Invalid scope"); + break; + } + if (native_thread) { +#ifdef _PR_PTHREADS + pthread_t tid; + printf("creating pthread\n"); + if (!pthread_create(&tid, NULL, start, arg)) + return((PRThread *) tid); + else + return (NULL); +#else + HANDLE thandle; + + printf("creating Windows thread\n"); + thandle = (HANDLE) _beginthreadex( + NULL, + stackSize, + (unsigned (__stdcall *)(void *))start, + arg, + 0, + NULL); + return((PRThread *) thandle); +#endif + } else { + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); + } +#else + return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize)); +#endif +} static void PR_CALLBACK File_Write(void *arg) { @@ -164,10 +231,10 @@ int offset, len; } -static void Misc_File_Tests(char *pathname) +static PRInt32 Misc_File_Tests(char *pathname) { PRFileDesc *fd_file; -int len; +int len, rv = 0; PRFileInfo file_info, file_info1; char tmpname[1024]; @@ -180,40 +247,47 @@ char tmpname[1024]; if (fd_file == NULL) { printf("testfile failed to create/open file %s\n",pathname); - return; + return -1; } if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { printf("testfile PR_GetFileInfo failed on file %s\n",pathname); + rv = -1; goto cleanup; } if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) { printf("testfile PR_Access failed on file %s\n",pathname); + rv = -1; goto cleanup; } if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) { printf("testfile PR_Access failed on file %s\n",pathname); + rv = -1; goto cleanup; } if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) { printf("testfile PR_Access failed on file %s\n",pathname); + rv = -1; goto cleanup; } if (PR_GetFileInfo(pathname, &file_info) < 0) { printf("testfile PR_GetFileInfo failed on file %s\n",pathname); - return; + rv = -1; + goto cleanup; } if (file_info.type != PR_FILE_FILE) { - printf( - "testfile PR_GetFileInfo returned incorrect type for file %s\n", + printf( + "testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n", pathname); + rv = -1; goto cleanup; } if (file_info.size != 0) { printf( "testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n", file_info.size, pathname); + rv = -1; goto cleanup; } file_info1 = file_info; @@ -221,16 +295,19 @@ char tmpname[1024]; len = PR_Available(fd_file); if (len < 0) { printf("testfile PR_Available failed on file %s\n",pathname); + rv = -1; goto cleanup; } else if (len != 0) { printf( "testfile PR_Available failed: expected/returned = %d/%d bytes\n", 0, len); + rv = -1; goto cleanup; } len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE); if (len < 0) { printf("testfile failed to write to file %s\n",pathname); + rv = -1; goto cleanup; } if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) { @@ -241,29 +318,36 @@ char tmpname[1024]; printf( "testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n", file_info.size, CHUNK_SIZE, pathname); + rv = -1; goto cleanup; } if (LL_NE(file_info.creationTime , file_info1.creationTime)) { printf( "testfile PR_GetFileInfo returned incorrect creation time: %s\n", pathname); + printf("ft = %lld, ft1 = %lld\n",file_info.creationTime, + file_info1.creationTime); + rv = -1; goto cleanup; } if (LL_CMP(file_info.modifyTime, > , file_info1.modifyTime)) { printf( "testfile PR_GetFileInfo returned incorrect modify time: %s\n", pathname); + rv = -1; goto cleanup; } len = PR_Available(fd_file); if (len < 0) { printf("testfile PR_Available failed on file %s\n",pathname); + rv = -1; goto cleanup; } else if (len != 0) { printf( "testfile PR_Available failed: expected/returned = %d/%d bytes\n", 0, len); + rv = -1; goto cleanup; } @@ -271,11 +355,13 @@ char tmpname[1024]; len = PR_Available(fd_file); if (len < 0) { printf("testfile PR_Available failed on file %s\n",pathname); - return; + rv = -1; + goto cleanup; } else if (len != CHUNK_SIZE) { printf( "testfile PR_Available failed: expected/returned = %d/%d bytes\n", CHUNK_SIZE, len); + rv = -1; goto cleanup; } PR_Close(fd_file); @@ -284,6 +370,7 @@ char tmpname[1024]; strcat(tmpname,".RENAMED"); if (PR_FAILURE == PR_Rename(pathname, tmpname)) { printf("testfile failed to rename file %s\n",pathname); + rv = -1; goto cleanup; } @@ -294,19 +381,24 @@ char tmpname[1024]; printf("testfile renamed to existing file %s\n",pathname); } - if ((PR_Delete(tmpname)) < 0) + if ((PR_Delete(tmpname)) < 0) { printf("testfile failed to unlink file %s\n",tmpname); + rv = -1; + } cleanup: - if ((PR_Delete(pathname)) < 0) + if ((PR_Delete(pathname)) < 0) { printf("testfile failed to unlink file %s\n",pathname); + rv = -1; + } + return rv; } static PRInt32 PR_CALLBACK FileTest(void) { PRDir *fd_dir; -int i, offset, len; +int i, offset, len, rv = 0; PRThread *t; PRThreadScope scope; File_Rdwr_Param *fparamp; @@ -321,7 +413,8 @@ File_Rdwr_Param *fparamp; fd_dir = PR_OpenDir(TEST_DIR); if (fd_dir == NULL) { printf("testfile failed to open dir %s\n",TEST_DIR); - return -1; + rv = -1; + goto cleanup; } PR_CloseDir(fd_dir); @@ -334,13 +427,15 @@ File_Rdwr_Param *fparamp; if (in_buf == NULL) { printf( "testfile failed to alloc buffer struct\n"); - return -1; + rv = -1; + goto cleanup; } out_buf = PR_NEW(buffer); if (out_buf == NULL) { printf( "testfile failed to alloc buffer struct\n"); - return -1; + rv = -1; + goto cleanup; } /* @@ -354,27 +449,21 @@ File_Rdwr_Param *fparamp; if (fparamp == NULL) { printf( "testfile failed to alloc File_Rdwr_Param struct\n"); - return -1; + rv = -1; + goto cleanup; } fparamp->pathname = pathname; fparamp->buf = out_buf->data + offset; fparamp->offset = offset; fparamp->len = len; memset(fparamp->buf, i, len); - /* - * Create LOCAL and GLOBAL Threads, alternately - */ - if (i % 1) - scope = PR_GLOBAL_THREAD; - else - scope = PR_LOCAL_THREAD; - t = PR_CreateThread(PR_USER_THREAD, + t = create_new_thread(PR_USER_THREAD, File_Write, (void *)fparamp, PR_PRIORITY_NORMAL, scope, PR_UNJOINABLE_THREAD, - 0); + 0, i); offset += len; } thread_count = i; @@ -396,26 +485,20 @@ File_Rdwr_Param *fparamp; if (fparamp == NULL) { printf( "testfile failed to alloc File_Rdwr_Param struct\n"); - return -1; + rv = -1; + goto cleanup; } fparamp->pathname = pathname; fparamp->buf = in_buf->data + offset; fparamp->offset = offset; fparamp->len = len; - /* - * Create LOCAL and GLOBAL Threads, alternately - */ - if (i % 1) - scope = PR_LOCAL_THREAD; - else - scope = PR_GLOBAL_THREAD; - t = PR_CreateThread(PR_USER_THREAD, + t = create_new_thread(PR_USER_THREAD, File_Read, (void *)fparamp, PR_PRIORITY_NORMAL, scope, PR_UNJOINABLE_THREAD, - 0); + 0, i); offset += len; if ((offset + len) > BUF_DATA_SIZE) break; @@ -430,27 +513,78 @@ File_Rdwr_Param *fparamp; if (memcmp(in_buf->data, out_buf->data, offset) != 0) { printf("File Test failed: file data corrupted\n"); + rv = -1; + goto cleanup; } if ((PR_Delete(pathname)) < 0) { printf("testfile failed to unlink file %s\n",pathname); - return -1; + rv = -1; + goto cleanup; } /* * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access */ - Misc_File_Tests(pathname); + if (Misc_File_Tests(pathname) < 0) { + rv = -1; + } +cleanup: if ((PR_RmDir(TEST_DIR)) < 0) { printf("testfile failed to rmdir %s\n", TEST_DIR); + rv = -1; + } + return rv; +} + +struct dirtest_arg { + PRMonitor *mon; + PRInt32 done; +}; + +static PRInt32 RunDirTest(void) +{ +int i; +PRThread *t; +PRMonitor *mon; +struct dirtest_arg thrarg; + + mon = PR_NewMonitor(); + if (!mon) { + printf("RunDirTest: Error - failed to create monitor\n"); + dirtest_failed = 1; return -1; } + thrarg.mon = mon; + + for (i = 0; i < NUM_DIRTEST_THREADS; i++) { + + thrarg.done= 0; + t = create_new_thread(PR_USER_THREAD, + DirTest, &thrarg, + PR_PRIORITY_NORMAL, + PR_LOCAL_THREAD, + PR_UNJOINABLE_THREAD, + 0, i); + if (!t) { + printf("RunDirTest: Error - failed to create thread\n"); + dirtest_failed = 1; + return -1; + } + PR_EnterMonitor(mon); + while (!thrarg.done) + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT); + PR_ExitMonitor(mon); + + } + PR_DestroyMonitor(mon); return 0; } -static PRInt32 PR_CALLBACK DirTest(void) +static PRInt32 PR_CALLBACK DirTest(void *arg) { +struct dirtest_arg *tinfo = (struct dirtest_arg *) arg; PRFileDesc *fd_file; PRDir *fd_dir; int i; @@ -763,6 +897,10 @@ HANDLE hfile; TEST_DIR, PR_GetError(), PR_GetOSError()); return -1; } + PR_EnterMonitor(tinfo->mon); + tinfo->done = 1; + PR_Notify(tinfo->mon); + PR_ExitMonitor(tinfo->mon); return 0; } @@ -774,6 +912,9 @@ HANDLE hfile; int main(int argc, char **argv) { +#ifdef WIN32 + PRUint32 len; +#endif #if defined(XP_UNIX) || defined(XP_OS2_EMX) int opt; extern char *optarg; @@ -802,14 +943,25 @@ int main(int argc, char **argv) printf("testfile: PR_NewMonitor failed\n"); exit(2); } +#ifdef WIN32 + len = GetTempPath(TMPDIR_LEN, testdir); + if ((len > 0) && (len < (TMPDIR_LEN - 7))) { + /* + * enough space for \prdir + */ + strcpy((testdir + len),"\prdir"); + TEST_DIR = testdir; + printf("TEST_DIR = %s\n",TEST_DIR); + } + +#endif if (FileTest() < 0) { printf("File Test failed\n"); exit(2); } printf("File Test passed\n"); - - if (DirTest() < 0) { + if ((RunDirTest() < 0) || dirtest_failed) { printf("Dir Test failed\n"); exit(2); } |