summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>1999-03-02 00:58:34 +0000
committerwtc%netscape.com <devnull@localhost>1999-03-02 00:58:34 +0000
commit45c8684d940dfeab4891550f8d0662b49547701b (patch)
tree14146e0b29d229d37a195165754924fc61cd1016
parentc5742d6455413019013f14c201c6994fa6643669 (diff)
downloadnspr-hg-45c8684d940dfeab4891550f8d0662b49547701b.tar.gz
Another update from the internal CVS repository /m/src to mozilla.org.
-rw-r--r--config/rules.mk4
-rw-r--r--pr/include/MANIFEST2
-rw-r--r--pr/include/nspr.h2
-rw-r--r--pr/include/prerr.h4
-rw-r--r--pr/include/prerror.h76
-rw-r--r--pr/include/prerrorinstall.h (renamed from pr/include/prerrorplugin.h)82
-rw-r--r--pr/include/private/primpl.h1
-rw-r--r--pr/src/Makefile2
-rw-r--r--pr/src/io/prfile.c36
-rw-r--r--pr/src/misc/compile-et.pl4
-rw-r--r--pr/src/misc/prerr.c24
-rw-r--r--pr/src/misc/prerr.et2
-rw-r--r--pr/src/misc/prerrortable.c66
-rw-r--r--pr/src/misc/prinit.c47
-rw-r--r--pr/src/nspr.rc84
-rw-r--r--pr/src/pthreads/ptthread.c47
-rw-r--r--pr/src/resource.h16
-rw-r--r--pr/src/threads/prrwlock.c207
-rw-r--r--pr/tests/Makefile6
-rw-r--r--pr/tests/errcodes.c148
-rw-r--r--pr/tests/rwlocktest.c28
-rw-r--r--pr/tests/socket.c105
-rw-r--r--pr/tests/testfile.c230
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);
}