Browse Source

completely shoot nspr

David Rose 19 years ago
parent
commit
baa0f8039c
83 changed files with 1135 additions and 1780 deletions
  1. 0 4
      dtool/Config.FreeBSD.pp
  2. 0 1
      dtool/Config.Win32.pp
  3. 11 28
      dtool/Config.pp
  4. 0 8
      dtool/LocalSetup.pp
  5. 6 9
      dtool/Package.pp
  6. 16 16
      dtool/pptempl/Global.pp
  7. 1 6
      dtool/src/dtoolbase/Sources.pp
  8. 0 5
      dtool/src/dtoolbase/atomicAdjust.h
  9. 0 140
      dtool/src/dtoolbase/atomicAdjustNsprImpl.I
  10. 0 62
      dtool/src/dtoolbase/atomicAdjustNsprImpl.h
  11. 0 1
      dtool/src/dtoolbase/dtoolbase_composite1.cxx
  12. 0 1
      dtool/src/dtoolbase/dtoolbase_composite2.cxx
  13. 0 7
      dtool/src/dtoolbase/mutexImpl.h
  14. 0 126
      dtool/src/dtoolbase/mutexNsprImpl.I
  15. 0 70
      dtool/src/dtoolbase/mutexNsprImpl.h
  16. 1 30
      dtool/src/dtoolbase/numeric_types.h
  17. 0 5
      dtool/src/dtoolbase/selectThreadImpl.h
  18. 3 1
      dtool/src/parser-inc/Sources.pp
  19. 0 0
      dtool/src/parser-inc/crypto.h
  20. 0 0
      dtool/src/parser-inc/pem.h
  21. 0 0
      dtool/src/parser-inc/rsa.h
  22. 1 0
      dtool/src/parser-inc/ssl.h
  23. 1 1
      panda/src/express/Sources.pp
  24. 16 4
      panda/src/nativenet/Sources.pp
  25. 21 0
      panda/src/nativenet/buffered_datagramconnection.cxx
  26. 18 1
      panda/src/nativenet/buffered_datagramconnection.h
  27. 72 0
      panda/src/nativenet/config_nativenet.cxx
  28. 32 0
      panda/src/nativenet/config_nativenet.h
  29. 9 3
      panda/src/nativenet/nativenet_composite1.cxx
  30. 1 0
      panda/src/nativenet/socket_address.h
  31. 1 0
      panda/src/nativenet/socket_fdset.h
  32. 4 8
      panda/src/nativenet/socket_ip.cxx
  33. 26 5
      panda/src/nativenet/socket_ip.h
  34. 4 10
      panda/src/nativenet/socket_tcp.cxx
  35. 23 3
      panda/src/nativenet/socket_tcp.h
  36. 21 0
      panda/src/nativenet/socket_tcp_listen.cxx
  37. 29 7
      panda/src/nativenet/socket_tcp_listen.h
  38. 7 8
      panda/src/nativenet/socket_tcp_ssl.cxx
  39. 37 14
      panda/src/nativenet/socket_tcp_ssl.h
  40. 21 0
      panda/src/nativenet/socket_udp.cxx
  41. 169 0
      panda/src/nativenet/socket_udp.h
  42. 21 0
      panda/src/nativenet/socket_udp_incoming.cxx
  43. 29 6
      panda/src/nativenet/socket_udp_incoming.h
  44. 21 0
      panda/src/nativenet/socket_udp_outgoing.cxx
  45. 19 2
      panda/src/nativenet/socket_udp_outgoing.h
  46. 8 8
      panda/src/net/Sources.pp
  47. 83 136
      panda/src/net/connection.cxx
  48. 7 9
      panda/src/net/connection.h
  49. 10 8
      panda/src/net/connectionListener.cxx
  50. 65 132
      panda/src/net/connectionManager.cxx
  51. 3 5
      panda/src/net/connectionManager.h
  52. 127 316
      panda/src/net/connectionReader.cxx
  53. 30 26
      panda/src/net/connectionReader.h
  54. 36 41
      panda/src/net/connectionWriter.cxx
  55. 16 9
      panda/src/net/connectionWriter.h
  56. 14 30
      panda/src/net/datagramQueue.cxx
  57. 4 12
      panda/src/net/datagramQueue.h
  58. 2 2
      panda/src/net/datagramTCPHeader.cxx
  59. 3 4
      panda/src/net/datagramTCPHeader.h
  60. 4 4
      panda/src/net/datagramUDPHeader.cxx
  61. 2 3
      panda/src/net/datagramUDPHeader.h
  62. 15 116
      panda/src/net/netAddress.cxx
  63. 4 5
      panda/src/net/netAddress.h
  64. 0 1
      panda/src/net/net_composite1.cxx
  65. 0 238
      panda/src/net/pprerror.cxx
  66. 0 2
      panda/src/net/queuedConnectionListener.h
  67. 2 2
      panda/src/net/queuedConnectionManager.cxx
  68. 1 3
      panda/src/net/queuedConnectionManager.h
  69. 5 14
      panda/src/net/queuedConnectionReader.cxx
  70. 2 3
      panda/src/net/queuedConnectionReader.h
  71. 5 16
      panda/src/net/queuedReturn.I
  72. 6 3
      panda/src/net/queuedReturn.h
  73. 3 8
      panda/src/net/recentConnectionReader.cxx
  74. 2 3
      panda/src/net/recentConnectionReader.h
  75. 2 2
      panda/src/net/test_raw_server.cxx
  76. 10 9
      panda/src/net/test_spam_client.cxx
  77. 9 7
      panda/src/net/test_spam_server.cxx
  78. 2 2
      panda/src/net/test_tcp_server.cxx
  79. 1 0
      panda/src/pipeline/Sources.pp
  80. 6 1
      panda/src/pstatclient/pStatClientImpl.cxx
  81. 1 1
      panda/src/pstatclient/pStatClientImpl.h
  82. 3 6
      pandatool/src/pstatserver/pStatServer.cxx
  83. 1 1
      pandatool/src/pstatserver/pStatServer.h

+ 0 - 4
dtool/Config.FreeBSD.pp

@@ -162,9 +162,6 @@
 #define PYTHON_IPATH /usr/local/include/python2.4
 #define PYTHON_IPATH /usr/local/include/python2.4
 #define PYTHON_LPATH /usr/local/lib/python2.4
 #define PYTHON_LPATH /usr/local/lib/python2.4
 
 
-#define NSPR_IPATH /usr/local/include/nspr
-#define NSPR_LPATH /usr/local/lib/nspr
-
 #define SSL_IPATH /usr/local/openssl
 #define SSL_IPATH /usr/local/openssl
 //#define SSL_097 1
 //#define SSL_097 1
 
 
@@ -190,4 +187,3 @@
 //#defer alt_ipath $[alt_ipath] /usr/local/include
 //#defer alt_ipath $[alt_ipath] /usr/local/include
 //#defer alt_lpath $[alt_lpath] /usr/local/lib
 //#defer alt_lpath $[alt_lpath] /usr/local/lib
 
 
-#defer NSPR_LIBS $[NSPR_LIBS] thr

+ 0 - 1
dtool/Config.Win32.pp

@@ -20,7 +20,6 @@
 // *******************************************************************
 // *******************************************************************
 
 
 // What additional flags should we pass to interrogate?
 // What additional flags should we pass to interrogate?
-// NSPR versions prior to 4.4 used _declspec instead of __declspec.
 #define SYSTEM_IGATE_FLAGS -longlong __int64 -D_X86_ -DWIN32_VC -D"_declspec(param)=" -D"__declspec(param)=" -D_near  -D_far -D__near  -D__far -D_WIN32 -D__stdcall -Dvolatile=
 #define SYSTEM_IGATE_FLAGS -longlong __int64 -D_X86_ -DWIN32_VC -D"_declspec(param)=" -D"__declspec(param)=" -D_near  -D_far -D__near  -D__far -D_WIN32 -D__stdcall -Dvolatile=
 
 
 // Additional flags to pass to the Tau instrumentor.
 // Additional flags to pass to the Tau instrumentor.

+ 11 - 28
dtool/Config.pp

@@ -398,22 +398,17 @@
 //#defer ALTERNATIVE_MALLOC $[or $[WINDOWS_PLATFORM],$[DO_MEMORY_USAGE],$[not $[HAVE_THREADS]]]
 //#defer ALTERNATIVE_MALLOC $[or $[WINDOWS_PLATFORM],$[DO_MEMORY_USAGE],$[not $[HAVE_THREADS]]]
 #define ALTERNATIVE_MALLOC
 #define ALTERNATIVE_MALLOC
 
 
-// Is NSPR installed, and where?  This is the Netscape Portable
-// Runtime library, downloadable as part of the Mozilla package from
-// mozilla.org.  It provides portable threading and networking
-// services to Panda.  Panda should compile without it, although
-// without any threading or networking capabilities; eventually,
-// native support for these capabilities may be added for certain
-// platforms.  See also HAVE_IPC and HAVE_NET.
-#define NSPR_IPATH /usr/include/nspr
-#define NSPR_LPATH
-#define NSPR_LIBS nspr4
-#defer HAVE_NSPR $[isfile $[NSPR_IPATH]/prtypes.h]
-
-// Define this true to build a native network implementation,
-// which does not require NSPR.
+// Define this true to build the low-level native network
+// implementation.  Normally this should be set true.
 #define WANT_NATIVE_NET 1
 #define WANT_NATIVE_NET 1
-#define NATIVE_NET_LIBS $[if $[WINDOWS_PLATFORM],Ws2_32.lib]
+#define NATIVE_NET_IPATH
+#define NATIVE_NET_LPATH
+#define NATIVE_NET_LIBS $[if $[WINDOWS_PLATFORM],wsock32.lib]
+
+// Do you want to build the high-level network interface?  This layers
+// on top of the low-level native_net interface, specified above.
+// Normally, if you build NATIVE_NET, you will also build NET.
+#defer HAVE_NET $[WANT_NATIVE_NET]
 
 
 // Is a third-party STL library installed, and where?  This is only
 // Is a third-party STL library installed, and where?  This is only
 // necessary if the default include and link lines that come with the
 // necessary if the default include and link lines that come with the
@@ -683,9 +678,8 @@
 // You should only turn this on if you have some threading library
 // You should only turn this on if you have some threading library
 // available (most people will have one).  Windows has one built-in.
 // available (most people will have one).  Windows has one built-in.
 // Linux uses Posix threads, which most Linuxes provide.
 // Linux uses Posix threads, which most Linuxes provide.
-// Alternatively, the NSPR library also provides a threading interface
-// that Panda can use.
 #define HAVE_THREADS
 #define HAVE_THREADS
+#define THREADS_LIBS $[if $[not $[WINDOWS_PLATFORM]],pthread]
 
 
 // Whether threading is defined or not, you might want to validate the
 // Whether threading is defined or not, you might want to validate the
 // thread and synchronization operations.  With threading enabled,
 // thread and synchronization operations.  With threading enabled,
@@ -703,17 +697,6 @@
 // than CPU's.  Even then, OS-based locking is probably better.
 // than CPU's.  Even then, OS-based locking is probably better.
 #define MUTEX_SPINLOCK
 #define MUTEX_SPINLOCK
 
 
-// Do you want to build the network interface?  What additional libraries
-// are required?  Currently, this requires NSPR.
-#define NET_IPATH
-#define NET_LPATH
-#if $[WINDOWS_PLATFORM]
-  #define NET_LIBS wsock32.lib
-#else
-  #define NET_LIBS
-#endif
-#defer HAVE_NET $[HAVE_NSPR]
-
 // Do you want to build the PStats interface, for graphical run-time
 // Do you want to build the PStats interface, for graphical run-time
 // performance statistics?  This requires NET to be available.  By
 // performance statistics?  This requires NET to be available.  By
 // default, we don't build PStats when OPTIMIZE = 4, although this is
 // default, we don't build PStats when OPTIMIZE = 4, although this is

+ 0 - 8
dtool/LocalSetup.pp

@@ -11,11 +11,6 @@
 
 
 #print
 #print
 #print Configuring support for the following optional third-party packages:
 #print Configuring support for the following optional third-party packages:
-#if $[HAVE_NSPR]
-#print + NSPR
-#else
-#print - Did not find NSPR
-#endif
 #if $[HAVE_OPENSSL]
 #if $[HAVE_OPENSSL]
 #print + OpenSSL
 #print + OpenSSL
 #else
 #else
@@ -181,9 +176,6 @@ $[cdefine MAYA_PRE_5_0]
 /* Define if we have SoftImage available. */
 /* Define if we have SoftImage available. */
 $[cdefine HAVE_SOFTIMAGE]
 $[cdefine HAVE_SOFTIMAGE]
 
 
-/* Define if we have NSPR installed.  */
-$[cdefine HAVE_NSPR]
-
 /* Define if we have OpenSSL installed.  */
 /* Define if we have OpenSSL installed.  */
 $[cdefine HAVE_OPENSSL]
 $[cdefine HAVE_OPENSSL]
 $[cdefine OPENSSL_097]
 $[cdefine OPENSSL_097]

+ 6 - 9
dtool/Package.pp

@@ -108,10 +108,12 @@
 #set PYTHON_FRAMEWORK $[unixfilename $[PYTHON_FRAMEWORK]]
 #set PYTHON_FRAMEWORK $[unixfilename $[PYTHON_FRAMEWORK]]
 #set HAVE_PYTHON $[HAVE_PYTHON]
 #set HAVE_PYTHON $[HAVE_PYTHON]
 
 
-#set NSPR_IPATH $[unixfilename $[NSPR_IPATH]]
-#set NSPR_LPATH $[unixfilename $[NSPR_LPATH]]
-#set NSPR_LIBS $[NSPR_LIBS]
-#set HAVE_NSPR $[HAVE_NSPR]
+#set NATIVE_NET_IPATH $[unixfilename $[NATIVE_NET_IPATH]]
+#set NATIVE_NET_LPATH $[unixfilename $[NATIVE_NET_LPATH]]
+#set NATIVE_NET_LIBS $[NATIVE_NET_LIBS]
+#set WANT_NATIVE_NET $[WANT_NATIVE_NET]
+
+#set HAVE_NET $[HAVE_NET]
 
 
 #set OPENSSL_IPATH $[unixfilename $[OPENSSL_IPATH]]
 #set OPENSSL_IPATH $[unixfilename $[OPENSSL_IPATH]]
 #set OPENSSL_LPATH $[unixfilename $[OPENSSL_LPATH]]
 #set OPENSSL_LPATH $[unixfilename $[OPENSSL_LPATH]]
@@ -238,11 +240,6 @@
 #set DEBUG_THREADS $[DEBUG_THREADS]
 #set DEBUG_THREADS $[DEBUG_THREADS]
 #set MUTEX_SPINLOCK $[MUTEX_SPINLOCK]
 #set MUTEX_SPINLOCK $[MUTEX_SPINLOCK]
 
 
-#set NET_IPATH $[unixfilename $[NET_IPATH]]
-#set NET_LPATH $[unixfilename $[NET_LPATH]]
-#set NET_LIBS $[NET_LIBS]
-#set HAVE_NET $[HAVE_NET]
-
 #set DO_PSTATS $[DO_PSTATS]
 #set DO_PSTATS $[DO_PSTATS]
 
 
 #set RAD_MSS_IPATH $[unixfilename $[RAD_MSS_IPATH]]
 #set RAD_MSS_IPATH $[unixfilename $[RAD_MSS_IPATH]]

+ 16 - 16
dtool/pptempl/Global.pp

@@ -97,12 +97,12 @@
   #define python_framework $[PYTHON_FRAMEWORK]
   #define python_framework $[PYTHON_FRAMEWORK]
 #endif
 #endif
 
 
-#if $[HAVE_NSPR]
-  #define nspr_ipath $[wildcard $[NSPR_IPATH]]
-  #define nspr_lpath $[wildcard $[NSPR_LPATH]]
-  #define nspr_cflags $[NSPR_CFLAGS]
-  #define nspr_libs $[NSPR_LIBS]
-  #define nspr_framework $[NSPR_FRAMEWORK]
+#if $[HAVE_THREADS]
+  #define threads_ipath $[wildcard $[THREADS_IPATH]]
+  #define threads_lpath $[wildcard $[THREADS_LPATH]]
+  #define threads_cflags $[THREADS_CFLAGS]
+  #define threads_libs $[THREADS_LIBS]
+  #define threads_framework $[THREADS_FRAMEWORK]
 #endif
 #endif
 
 
 #if $[HAVE_OPENSSL]
 #if $[HAVE_OPENSSL]
@@ -458,8 +458,8 @@
 // on the various external packages this particular target claims to
 // on the various external packages this particular target claims to
 // require.
 // require.
 #defun get_cflags
 #defun get_cflags
-  // hack to add stl,nspr,python.  should be removed
-  #define alt_cflags $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_cflags] $[nspr_cflags] $[python_cflags]]
+  // hack to add stl,python.  should be removed
+  #define alt_cflags $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_cflags] $[python_cflags]]
 
 
   #foreach package $[use_packages]
   #foreach package $[use_packages]
     #set alt_cflags $[alt_cflags] $[$[package]_cflags]
     #set alt_cflags $[alt_cflags] $[$[package]_cflags]
@@ -472,8 +472,8 @@
 // on the various external packages this particular target claims to
 // on the various external packages this particular target claims to
 // require.
 // require.
 #defun get_lflags
 #defun get_lflags
-  // hack to add stl,nspr,python.  should be removed
-  #define alt_lflags $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_lflags] $[nspr_lflags] $[python_lflags]]
+  // hack to add stl,python.  should be removed
+  #define alt_lflags $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_lflags] $[python_lflags]]
 
 
   #foreach package $[use_packages]
   #foreach package $[use_packages]
     #set alt_lflags $[alt_lflags] $[$[package]_lflags]
     #set alt_lflags $[alt_lflags] $[$[package]_lflags]
@@ -487,8 +487,8 @@
 // claims to require.  This returns a space-separated set of directory
 // claims to require.  This returns a space-separated set of directory
 // names only; the -I switch is not included here.
 // names only; the -I switch is not included here.
 #defun get_ipath
 #defun get_ipath
-  // hack to add stl,nspr,python.  should be removed
-  #define alt_ipath $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_ipath] $[nspr_ipath] $[python_ipath]]
+  // hack to add stl,python.  should be removed
+  #define alt_ipath $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_ipath] $[python_ipath]]
 
 
   #foreach package $[use_packages]
   #foreach package $[use_packages]
     #set alt_ipath $[alt_ipath] $[$[package]_ipath]
     #set alt_ipath $[alt_ipath] $[$[package]_ipath]
@@ -502,7 +502,7 @@
 // target claims to require.  This returns a space-separated set of
 // target claims to require.  This returns a space-separated set of
 // directory names only; the -L switch is not included here.
 // directory names only; the -L switch is not included here.
 #defun get_lpath
 #defun get_lpath
-  #define alt_lpath $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_lpath] $[nspr_lpath] $[python_lpath]]
+  #define alt_lpath $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_lpath] $[python_lpath]]
 
 
   #if $[WINDOWS_PLATFORM]
   #if $[WINDOWS_PLATFORM]
     #set alt_lpath $[WIN32_PLATFORMSDK_LIBPATH] $[alt_lpath]
     #set alt_lpath $[WIN32_PLATFORMSDK_LIBPATH] $[alt_lpath]
@@ -520,7 +520,7 @@
 // target claims to require.  This returns a space-separated set of
 // target claims to require.  This returns a space-separated set of
 // directory names only; the -F switch is not included here.
 // directory names only; the -F switch is not included here.
 #defun get_fpath
 #defun get_fpath
-  #define alt_fpath $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_fpath] $[nspr_fpath] $[python_fpath]]
+  #define alt_fpath $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_fpath] $[python_fpath]]
 
 
   #foreach package $[use_packages]
   #foreach package $[use_packages]
     #set alt_fpath $[alt_fpath] $[$[package]_fpath]
     #set alt_fpath $[alt_fpath] $[$[package]_fpath]
@@ -534,7 +534,7 @@
 // target claims to require.  This returns a space-separated set of
 // target claims to require.  This returns a space-separated set of
 // framework names only; the -framework switch is not included here.
 // framework names only; the -framework switch is not included here.
 #defun get_frameworks
 #defun get_frameworks
-  #define alt_frameworks $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_framework] $[nspr_framework] $[python_framework]]
+  #define alt_frameworks $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_framework] $[python_framework]]
 
 
   #if $[OSX_PLATFORM]
   #if $[OSX_PLATFORM]
     #set alt_frameworks $[alt_frameworks] $[OSX_SYS_FRAMEWORKS]
     #set alt_frameworks $[alt_frameworks] $[OSX_SYS_FRAMEWORKS]
@@ -553,7 +553,7 @@
 // space-separated set of library names only; the -l switch is not
 // space-separated set of library names only; the -l switch is not
 // included here.
 // included here.
 #defun get_libs
 #defun get_libs
-  #define alt_libs $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_libs] $[nspr_libs] $[python_libs]]
+  #define alt_libs $[if $[IGNORE_LIB_DEFAULTS_HACK],,$[stl_libs] $[python_libs]]
 
 
   #define alt_libs $[alt_libs] $[EXTRA_LIBS]
   #define alt_libs $[alt_libs] $[EXTRA_LIBS]
 
 

+ 1 - 6
dtool/src/dtoolbase/Sources.pp

@@ -1,4 +1,5 @@
 #define SELECT_TAU select.tau
 #define SELECT_TAU select.tau
+#define USE_PACKAGES threads
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET dtoolbase
   #define TARGET dtoolbase
@@ -10,7 +11,6 @@
     atomicAdjust.h \
     atomicAdjust.h \
     atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
     atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
     atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
     atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
-    atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \
     atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
     atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
     atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
     atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
     cmath.I cmath.h \
     cmath.I cmath.h \
@@ -22,7 +22,6 @@
     memoryBase.h \
     memoryBase.h \
     mutexImpl.h \
     mutexImpl.h \
     mutexDummyImpl.h mutexDummyImpl.I \
     mutexDummyImpl.h mutexDummyImpl.I \
-    mutexNsprImpl.h mutexNsprImpl.I \
     mutexLinuxImpl.h mutexLinuxImpl.I \
     mutexLinuxImpl.h mutexLinuxImpl.I \
     mutexPosixImpl.h mutexPosixImpl.I \
     mutexPosixImpl.h mutexPosixImpl.I \
     mutexWin32Impl.h mutexWin32Impl.I \
     mutexWin32Impl.h mutexWin32Impl.I \
@@ -44,13 +43,11 @@
     addHash.cxx \
     addHash.cxx \
     atomicAdjustDummyImpl.cxx \
     atomicAdjustDummyImpl.cxx \
     atomicAdjustI386Impl.cxx \
     atomicAdjustI386Impl.cxx \
-    atomicAdjustNsprImpl.cxx \
     atomicAdjustPosixImpl.cxx \
     atomicAdjustPosixImpl.cxx \
     atomicAdjustWin32Impl.cxx \
     atomicAdjustWin32Impl.cxx \
     dtoolbase.cxx \
     dtoolbase.cxx \
     memoryBase.cxx \
     memoryBase.cxx \
     mutexDummyImpl.cxx \
     mutexDummyImpl.cxx \
-    mutexNsprImpl.cxx \
     mutexLinuxImpl.cxx \
     mutexLinuxImpl.cxx \
     mutexPosixImpl.cxx \
     mutexPosixImpl.cxx \
     mutexWin32Impl.cxx \
     mutexWin32Impl.cxx \
@@ -65,7 +62,6 @@
     atomicAdjust.h \
     atomicAdjust.h \
     atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
     atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
     atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
     atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
-    atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \
     atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
     atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
     atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
     atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
     cmath.I cmath.h \
     cmath.I cmath.h \
@@ -76,7 +72,6 @@
     memoryBase.h \
     memoryBase.h \
     mutexImpl.h \
     mutexImpl.h \
     mutexDummyImpl.h mutexDummyImpl.I \
     mutexDummyImpl.h mutexDummyImpl.I \
-    mutexNsprImpl.h mutexNsprImpl.I \
     mutexLinuxImpl.h mutexLinuxImpl.I \
     mutexLinuxImpl.h mutexLinuxImpl.I \
     mutexPosixImpl.h mutexPosixImpl.I \
     mutexPosixImpl.h mutexPosixImpl.I \
     mutexWin32Impl.h mutexWin32Impl.I \
     mutexWin32Impl.h mutexWin32Impl.I \

+ 0 - 5
dtool/src/dtoolbase/atomicAdjust.h

@@ -60,11 +60,6 @@ typedef AtomicAdjustWin32Impl AtomicAdjust;
 #include "atomicAdjustPosixImpl.h"
 #include "atomicAdjustPosixImpl.h"
 typedef AtomicAdjustPosixImpl AtomicAdjust;
 typedef AtomicAdjustPosixImpl AtomicAdjust;
 
 
-#elif defined(THREAD_NSPR_IMPL)
-
-#include "atomicAdjustNsprImpl.h"
-typedef AtomicAdjustNsprImpl AtomicAdjust;
-
 #endif
 #endif
 
 
 #endif
 #endif

+ 0 - 140
dtool/src/dtoolbase/atomicAdjustNsprImpl.I

@@ -1,140 +0,0 @@
-// Filename: atomicAdjustNsprImpl.I
-// Created by:  drose (09Aug02)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::inc
-//       Access: Public, Static
-//  Description: Atomically increments the indicated variable.
-////////////////////////////////////////////////////////////////////
-INLINE void AtomicAdjustNsprImpl::
-inc(TVOLATILE PN_int32 &var) {
-  PR_AtomicIncrement((PRInt32 *)&var);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::dec
-//       Access: Public, Static
-//  Description: Atomically decrements the indicated variable and
-//               returns true if the new value is nonzero, false if it
-//               is zero.
-////////////////////////////////////////////////////////////////////
-INLINE bool AtomicAdjustNsprImpl::
-dec(TVOLATILE PN_int32 &var) {
-  return (PR_AtomicDecrement((PRInt32 *)&var) != 0);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::set
-//       Access: Public, Static
-//  Description: Atomically changes the indicated variable and
-//               returns the original value.
-////////////////////////////////////////////////////////////////////
-INLINE PN_int32 AtomicAdjustNsprImpl::
-set(TVOLATILE PN_int32 &var, PN_int32 new_value) {
-  return PR_AtomicSet((PRInt32 *)&var, new_value);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::get
-//       Access: Public, Static
-//  Description: Atomically retrieves the snapshot value of the
-//               indicated variable.  This is the only guaranteed safe
-//               way to retrieve the value that other threads might be
-//               asynchronously setting, incrementing, or decrementing
-//               (via other AtomicAjust methods).
-////////////////////////////////////////////////////////////////////
-INLINE PN_int32 AtomicAdjustNsprImpl::
-get(const TVOLATILE PN_int32 &var) {
-  return var;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::set_ptr
-//       Access: Public, Static
-//  Description: Atomically changes the indicated variable and
-//               returns the original value.
-////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustNsprImpl::
-set_ptr(void * TVOLATILE &var, void *new_value) {
-  return (void *)PR_AtomicSet((PRInt32 *)&var, (PRInt32)new_value);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::get_ptr
-//       Access: Public, Static
-//  Description: Atomically retrieves the snapshot value of the
-//               indicated variable.  This is the only guaranteed safe
-//               way to retrieve the value that other threads might be
-//               asynchronously setting, incrementing, or decrementing
-//               (via other AtomicAjust methods).
-////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustNsprImpl::
-get_ptr(void * const TVOLATILE &var) {
-  return var;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::compare_and_exchange
-//       Access: Public, Static
-//  Description: Atomic compare and exchange.  
-//
-//               If mem is equal to old_value, store new_value in mem.
-//               In either case, return the original value of mem.
-//               The caller can test for success by comparing
-//               return_value == old_value.
-//
-//               The atomic function expressed in pseudo-code:
-//
-//                 orig_value = mem;
-//                 if (mem == old_value) {
-//                   mem = new_value;
-//                 }
-//                 return orig_value;
-//
-////////////////////////////////////////////////////////////////////
-INLINE PN_int32 AtomicAdjustNsprImpl::
-compare_and_exchange(TVOLATILE PN_int32 &mem, PN_int32 old_value,
-                     PN_int32 new_value) {
-  PR_Lock(_mutex);
-  PN_int32 orig_value = mem;
-  if (mem == old_value) {
-    mem = new_value;
-  }
-  PR_Unlock(_mutex);
-  return orig_value;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: AtomicAdjustNsprImpl::compare_and_exchange_ptr
-//       Access: Public, Static
-//  Description: Atomic compare and exchange.  
-//
-//               As above, but works on pointers instead of integers.
-////////////////////////////////////////////////////////////////////
-INLINE void *AtomicAdjustNsprImpl::
-compare_and_exchange_ptr(void * TVOLATILE &mem, void *old_value,
-                         void *new_value) {
-  PR_Lock(_mutex);
-  void *orig_value = mem;
-  if (mem == old_value) {
-    mem = new_value;
-  }
-  PR_Unlock(_mutex);
-  return orig_value;
-}

+ 0 - 62
dtool/src/dtoolbase/atomicAdjustNsprImpl.h

@@ -1,62 +0,0 @@
-// Filename: atomicAdjustNsprImpl.h
-// Created by:  drose (09Aug02)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef ATOMICADJUSTNSPRIMPL_H
-#define ATOMICADJUSTNSPRIMPL_H
-
-#include "dtoolbase.h"
-#include "selectThreadImpl.h"
-
-#ifdef HAVE_NSPR
-
-#include "numeric_types.h"
-
-#include <pratom.h>
-#include <prlock.h>
-
-////////////////////////////////////////////////////////////////////
-//       Class : AtomicAdjustNsprImpl
-// Description : Uses NSPR to implement atomic adjustments.
-////////////////////////////////////////////////////////////////////
-class EXPCL_DTOOL AtomicAdjustNsprImpl {
-public:
-  INLINE static void inc(TVOLATILE PN_int32 &var);
-  INLINE static bool dec(TVOLATILE PN_int32 &var);
-  INLINE static PN_int32 set(TVOLATILE PN_int32 &var, PN_int32 new_value);
-  INLINE static PN_int32 get(const TVOLATILE PN_int32 &var);
-
-  INLINE static void *set_ptr(void * TVOLATILE &var, void *new_value);
-  INLINE static void *get_ptr(void * const TVOLATILE &var);
-
-  INLINE static PN_int32 compare_and_exchange(TVOLATILE PN_int32 &mem, 
-                                              PN_int32 old_value,
-                                              PN_int32 new_value);
-
-  INLINE static void *compare_and_exchange_ptr(void * TVOLATILE &mem, 
-                                               void *old_value,
-                                               void *new_value);
-
-private:
-  static PRLock *_mutex;
-};
-
-#include "atomicAdjustNsprImpl.I"
-
-#endif  // HAVE_NSPR
-
-#endif

+ 0 - 1
dtool/src/dtoolbase/dtoolbase_composite1.cxx

@@ -1,7 +1,6 @@
 #include "addHash.cxx"
 #include "addHash.cxx"
 #include "atomicAdjustDummyImpl.cxx"
 #include "atomicAdjustDummyImpl.cxx"
 #include "atomicAdjustI386Impl.cxx"
 #include "atomicAdjustI386Impl.cxx"
-#include "atomicAdjustNsprImpl.cxx"
 #include "atomicAdjustPosixImpl.cxx"
 #include "atomicAdjustPosixImpl.cxx"
 #include "atomicAdjustWin32Impl.cxx"
 #include "atomicAdjustWin32Impl.cxx"
 #include "dtoolbase.cxx"
 #include "dtoolbase.cxx"

+ 0 - 1
dtool/src/dtoolbase/dtoolbase_composite2.cxx

@@ -1,5 +1,4 @@
 #include "mutexDummyImpl.cxx"
 #include "mutexDummyImpl.cxx"
-#include "mutexNsprImpl.cxx"
 #include "mutexLinuxImpl.cxx"
 #include "mutexLinuxImpl.cxx"
 #include "mutexPosixImpl.cxx"
 #include "mutexPosixImpl.cxx"
 #include "mutexWin32Impl.cxx"
 #include "mutexWin32Impl.cxx"

+ 0 - 7
dtool/src/dtoolbase/mutexImpl.h

@@ -55,13 +55,6 @@ typedef MutexPosixImpl MutexImpl;
 typedef ReMutexPosixImpl ReMutexImpl;
 typedef ReMutexPosixImpl ReMutexImpl;
 #define HAVE_REMUTEXIMPL 1
 #define HAVE_REMUTEXIMPL 1
 
 
-#elif defined(THREAD_NSPR_IMPL)
-
-#include "mutexNsprImpl.h"
-typedef MutexNsprImpl MutexImpl;
-typedef ReMutexNsprImpl ReMutexImpl;
-#define HAVE_REMUTEXIMPL 1
-
 #endif
 #endif
 
 
 #endif
 #endif

+ 0 - 126
dtool/src/dtoolbase/mutexNsprImpl.I

@@ -1,126 +0,0 @@
-// Filename: mutexNsprImpl.I
-// Created by:  drose (08Aug02)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: MutexNsprImpl::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE MutexNsprImpl::
-MutexNsprImpl() {
-  _lock = PR_NewLock();
-  assert(_lock != (PRLock *)NULL);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: MutexNsprImpl::Destructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE MutexNsprImpl::
-~MutexNsprImpl() {
-  PR_DestroyLock(_lock);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: MutexNsprImpl::lock
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE void MutexNsprImpl::
-lock() {
-  PR_Lock(_lock);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: MutexNsprImpl::try_lock
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE bool MutexNsprImpl::
-try_lock() {
-  // NSPR doesn't define a try_lock function.  Too bad.  We just
-  // report that it would always block (since we don't know).
-  return false;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: MutexNsprImpl::release
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE void MutexNsprImpl::
-release() {
-  int status = PR_Unlock(_lock);
-  assert(status == PR_SUCCESS);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReMutexNsprImpl::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE ReMutexNsprImpl::
-ReMutexNsprImpl() {
-  _monitor = PR_NewMonitor();
-  assert(_monitor != (PRMonitor *)NULL);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReMutexNsprImpl::Destructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE ReMutexNsprImpl::
-~ReMutexNsprImpl() {
-  PR_DestroyMonitor(_monitor);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReMutexNsprImpl::lock
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE void ReMutexNsprImpl::
-lock() {
-  PR_EnterMonitor(_monitor);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReMutexNsprImpl::try_lock
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE bool ReMutexNsprImpl::
-try_lock() {
-  // NSPR doesn't define a try_lock function.  Too bad.  We just
-  // report that it would always block (since we don't know).
-  return false;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: ReMutexNsprImpl::release
-//       Access: Public
-//  Description: 
-////////////////////////////////////////////////////////////////////
-INLINE void ReMutexNsprImpl::
-release() {
-  int status = PR_ExitMonitor(_monitor);
-  assert(status == PR_SUCCESS);
-}

+ 0 - 70
dtool/src/dtoolbase/mutexNsprImpl.h

@@ -1,70 +0,0 @@
-// Filename: mutexNsprImpl.h
-// Created by:  drose (08Aug02)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#ifndef MUTEXNSPRIMPL_H
-#define MUTEXNSPRIMPL_H
-
-#include "dtoolbase.h"
-#include "selectThreadImpl.h"
-
-#ifdef HAVE_NSPR
-
-#include <prlock.h>
-#include <prmon.h>
-#include <assert.h>
-
-////////////////////////////////////////////////////////////////////
-//       Class : MutexNsprImpl
-// Description : Uses NSPR to implement a mutex.
-////////////////////////////////////////////////////////////////////
-class EXPCL_DTOOL MutexNsprImpl {
-public:
-  INLINE MutexNsprImpl();
-  INLINE ~MutexNsprImpl();
-
-  INLINE void lock();
-  INLINE bool try_lock();
-  INLINE void release();
-
-private:
-  PRLock *_lock;
-  friend class ConditionVarNsprImpl;
-};
-
-////////////////////////////////////////////////////////////////////
-//       Class : ReMutexNsprImpl
-// Description : Uses NSPR to implement a reMutex.
-////////////////////////////////////////////////////////////////////
-class EXPCL_DTOOL ReMutexNsprImpl {
-public:
-  INLINE ReMutexNsprImpl();
-  INLINE ~ReMutexNsprImpl();
-
-  INLINE void lock();
-  INLINE bool try_lock();
-  INLINE void release();
-
-private:
-  PRMonitor *_monitor;
-};
-
-#include "mutexNsprImpl.I"
-
-#endif  // HAVE_NSPR
-
-#endif

+ 1 - 30
dtool/src/dtoolbase/numeric_types.h

@@ -25,34 +25,7 @@
 // the various numeric types for unsigned and signed numbers of
 // the various numeric types for unsigned and signed numbers of
 // various widths.
 // various widths.
 
 
-// At the present, we use the logic in NSPR to determine this for us.
-// Later (especially for non-NSPR platforms) we'll have to do the work
-// ourselves.
-
-
-#ifdef HAVE_NSPR
-
-#include <prtypes.h>
-
-typedef PRInt8 PN_int8;
-typedef PRInt16 PN_int16;
-typedef PRInt32 PN_int32;
-typedef PRInt64 PN_int64;
-
-typedef PRUint8 PN_uint8;
-typedef PRUint16 PN_uint16;
-typedef PRUint32 PN_uint32;
-typedef PRUint64 PN_uint64;
-
-typedef PRFloat64 PN_float64;
-
-// NSPR doesn't define a float32.
-typedef float PN_float32;
-
-#else // HAVE_NSPR
-
-// Without NSPR, and without any other information, we need some
-// fallback.  For now, we'll just assume a typical environment.
+// For now, we'll just assume a typical 32-bit environment.
 
 
 typedef signed char PN_int8;
 typedef signed char PN_int8;
 typedef short PN_int16;
 typedef short PN_int16;
@@ -73,8 +46,6 @@ typedef unsigned long long PN_uint64;
 typedef double PN_float64;
 typedef double PN_float64;
 typedef float PN_float32;
 typedef float PN_float32;
 
 
-#endif  // HAVE_NSPR
-
 #endif
 #endif
 
 
 
 

+ 0 - 5
dtool/src/dtoolbase/selectThreadImpl.h

@@ -64,11 +64,6 @@
 // Posix threads are nice.
 // Posix threads are nice.
 #define THREAD_POSIX_IMPL 1
 #define THREAD_POSIX_IMPL 1
 
 
-#elif defined(HAVE_NSPR)
-
-// If NSPR is available, use that.
-#define THREAD_NSPR_IMPL 1
-
 #else
 #else
 
 
 // This is a configuration error.  For some reason, HAVE_THREADS is
 // This is a configuration error.  For some reason, HAVE_THREADS is

+ 3 - 1
dtool/src/parser-inc/Sources.pp

@@ -3,7 +3,9 @@
     pair pthread.h queue set stack stdcompare.h stdtypedefs.h \
     pair pthread.h queue set stack stdcompare.h stdtypedefs.h \
     string vector windows.h winsock2.h zlib.h files.h hex.h \
     string vector windows.h winsock2.h zlib.h files.h hex.h \
     md5.h evp.h bits/pthreadtypes.h \
     md5.h evp.h bits/pthreadtypes.h \
-    openssl/md5.h openssl/evp.h openssl/rand.h openssl/ssl.h openssl/x509.h openssl/err.h \
+    openssl/md5.h openssl/evp.h openssl/rand.h openssl/ssl.h \
+    openssl/x509.h openssl/err.h openssl/rsa.h openssl/crypto.h \
+    openssl/pem.h \
     nurbs.hh stddef.h krb5.h MainHelix.h dllpath.h hxcom.h \
     nurbs.hh stddef.h krb5.h MainHelix.h dllpath.h hxcom.h \
     hxcomm.h hxcore.h hxengin.h hxerror.h hxfiles.h hxtbuf.h \
     hxcomm.h hxcore.h hxengin.h hxerror.h hxfiles.h hxtbuf.h \
     hxtbuff.h hxwin.h Python.h Cg/cg.h Cg/cgGL.h \
     hxtbuff.h hxwin.h Python.h Cg/cg.h Cg/cgGL.h \

+ 0 - 0
dtool/src/parser-inc/crypto.h


+ 0 - 0
dtool/src/parser-inc/pem.h


+ 0 - 0
dtool/src/parser-inc/rsa.h


+ 1 - 0
dtool/src/parser-inc/ssl.h

@@ -9,5 +9,6 @@ struct EVP_PKEY;
 struct X509;
 struct X509;
 struct X509_STORE;
 struct X509_STORE;
 struct X509_NAME;
 struct X509_NAME;
+struct SSL;
 
 
 #endif
 #endif

+ 1 - 1
panda/src/express/Sources.pp

@@ -4,7 +4,7 @@
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET express
   #define TARGET express
-  #define USE_PACKAGES nspr net zlib openssl
+  #define USE_PACKAGES zlib openssl
   
   
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
 
 

+ 16 - 4
panda/src/nativenet/Sources.pp

@@ -5,7 +5,7 @@
     dtoolutil:c dtoolbase:c prc:c dtool:m
     dtoolutil:c dtoolbase:c prc:c dtool:m
 
 
 #define BUILD_DIRECTORY $[WANT_NATIVE_NET]
 #define BUILD_DIRECTORY $[WANT_NATIVE_NET]
-#define USE_PACKAGES native_net
+#define USE_PACKAGES native_net openssl
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET nativenet
   #define TARGET nativenet
@@ -19,12 +19,22 @@
 	socket_tcp_listen.h time_accumulator.h time_out.h \
 	socket_tcp_listen.h time_accumulator.h time_out.h \
 	socket_address.h \
 	socket_address.h \
         socket_portable.h  time_base.h time_span.h buffered_datagramwriter.h \
         socket_portable.h  time_base.h time_span.h buffered_datagramwriter.h \
-        socket_base.h socket_selector.h socket_udp_incoming.h time_clock.h \
+        socket_base.h socket_selector.h \
+        socket_udp.h \
+        socket_udp_incoming.h time_clock.h \
         membuffer.h membuffer.i socket_fdset.h socket_tcp.h \
         membuffer.h membuffer.i socket_fdset.h socket_tcp.h \
 	socket_udp_outgoing.h time_general.h
 	socket_udp_outgoing.h time_general.h
         
         
-        
   #define INCLUDED_SOURCES \
   #define INCLUDED_SOURCES \
+    buffered_datagramconnection.cxx \
+    config_nativenet.cxx \
+    socket_ip.cxx \
+    socket_tcp.cxx \
+    socket_tcp_listen.cxx \
+    socket_tcp_ssl.cxx \
+    socket_udp.cxx \
+    socket_udp_incoming.cxx \
+    socket_udp_outgoing.cxx
   
   
   #define INSTALL_HEADERS \
   #define INSTALL_HEADERS \
         buffered_datagramconnection.h \
         buffered_datagramconnection.h \
@@ -33,7 +43,9 @@
 	buffered_datagramreader.h buffered_datagramreader.i \
 	buffered_datagramreader.h buffered_datagramreader.i \
 	socket_address.h \
 	socket_address.h \
         socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
         socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
-        socket_base.h socket_selector.h socket_udp_incoming.h time_clock.h \
+        socket_base.h socket_selector.h \
+        socket_udp.h \
+        socket_udp_incoming.h time_clock.h \
         membuffer.h membuffer.i socket_fdset.h socket_tcp.h \
         membuffer.h membuffer.i socket_fdset.h socket_tcp.h \
 	socket_udp_outgoing.h time_general.h
 	socket_udp_outgoing.h time_general.h
 
 

+ 21 - 0
panda/src/nativenet/buffered_datagramconnection.cxx

@@ -0,0 +1,21 @@
+// Filename: buffered_datagramconnection.cxx
+// Created by:  drose (05Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "buffered_datagramconnection.h"
+
+TypeHandle Buffered_DatagramConnection::_type_handle;

+ 18 - 1
panda/src/nativenet/buffered_datagramconnection.h

@@ -26,7 +26,7 @@
 //      3. Socket is open and  writable.. ( Fully powered up )...
 //      3. Socket is open and  writable.. ( Fully powered up )...
 //
 //
 ///////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////
-class EXPCL_PANDA Buffered_DatagramConnection : protected Socket_TCP
+class EXPCL_PANDA Buffered_DatagramConnection : public Socket_TCP
 {
 {
 private:
 private:
   struct AddressQueue : private pvector<Socket_Address> // this is used to do a round robin for addres to connect to ..
   struct AddressQueue : private pvector<Socket_Address> // this is used to do a round robin for addres to connect to ..
@@ -89,7 +89,24 @@ private:
   friend class Buffered_DatagramReader;
   friend class Buffered_DatagramReader;
   friend class Buffered_DatagramWriter;
   friend class Buffered_DatagramWriter;
 
 
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_IP::init_type();
+    register_type(_type_handle, "Buffered_DatagramConnection",
+                  Socket_IP::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 // Function name	: Buffered_DatagramConnection::ClearAll
 // Function name	: Buffered_DatagramConnection::ClearAll
 // Description	    :  used to do a full reset of buffers
 // Description	    :  used to do a full reset of buffers

+ 72 - 0
panda/src/nativenet/config_nativenet.cxx

@@ -0,0 +1,72 @@
+// Filename: config_nativenet.cxx
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "config_nativenet.h"
+
+#include "socket_ip.h"
+#include "socket_tcp.h"
+#include "socket_tcp_listen.h"
+#include "socket_tcp_ssl.h"
+#include "socket_udp_incoming.h"
+#include "socket_udp_outgoing.h"
+#include "socket_udp.h"
+#include "socket_portable.h"
+#include "buffered_datagramconnection.h"
+#include "pandaSystem.h"
+
+#include "dconfig.h"
+
+Configure(config_nativenet);
+NotifyCategoryDef(nativenet, "");
+
+ConfigureFn(config_nativenet) {
+  init_libnativenet();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: init_libnativenet
+//  Description: Initializes the library.  This must be called at
+//               least once before any of the functions or classes in
+//               this library can be used.  Normally it will be
+//               called by the static initializers and need not be
+//               called explicitly, but special cases exist.
+////////////////////////////////////////////////////////////////////
+void
+init_libnativenet() {
+  static bool initialized = false;
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+
+  Socket_IP::init_type();
+  Socket_TCP::init_type();
+  Socket_TCP_Listen::init_type();
+  Socket_TCP_SSL::init_type();
+  Socket_UDP_Incoming::init_type();
+  Socket_UDP_Outgoing::init_type();
+  Socket_UDP::init_type();
+  Buffered_DatagramConnection::init_type();
+
+  PandaSystem *ps = PandaSystem::get_global_ptr();
+  ps->add_system("nativenet");
+
+  init_network();
+}
+

+ 32 - 0
panda/src/nativenet/config_nativenet.h

@@ -0,0 +1,32 @@
+// Filename: config_nativenet.h
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_NATIVENET_H
+#define CONFIG_NATIVENET_H
+
+#include "pandabase.h"
+#include "notifyCategoryProxy.h"
+
+// Configure variables for nativenet package.
+
+NotifyCategoryDecl(nativenet, EXPCL_PANDA, EXPTP_PANDA);
+
+extern EXPCL_PANDA void init_libnativenet();
+
+#endif
+

+ 9 - 3
panda/src/nativenet/nativenet_composite1.cxx

@@ -1,3 +1,9 @@
-#include "socket_base.h"
-
-
+#include "buffered_datagramconnection.cxx"
+#include "config_nativenet.cxx"
+#include "socket_ip.cxx"
+#include "socket_tcp.cxx"
+#include "socket_tcp_listen.cxx"
+#include "socket_tcp_ssl.cxx"
+#include "socket_udp.cxx"
+#include "socket_udp_incoming.cxx"
+#include "socket_udp_outgoing.cxx"

+ 1 - 0
panda/src/nativenet/socket_address.h

@@ -3,6 +3,7 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 #include "numeric_types.h"
 #include "numeric_types.h"
+#include "socket_portable.h"
 
 
 ///////////////////////////////////
 ///////////////////////////////////
 // Class : Socket_Address
 // Class : Socket_Address

+ 1 - 0
panda/src/nativenet/socket_fdset.h

@@ -14,6 +14,7 @@
 #include "pandabase.h"
 #include "pandabase.h"
 #include "numeric_types.h"
 #include "numeric_types.h"
 #include "time_base.h"
 #include "time_base.h"
+#include "socket_ip.h"
 
 
 class Socket_fdset
 class Socket_fdset
 {
 {

+ 4 - 8
dtool/src/dtoolbase/mutexNsprImpl.cxx → panda/src/nativenet/socket_ip.cxx

@@ -1,5 +1,5 @@
-// Filename: mutexNsprImpl.cxx
-// Created by:  drose (09Aug02)
+// Filename: socket_ip.cxx
+// Created by:  drose (01Mar07)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //
@@ -16,10 +16,6 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-#include "selectThreadImpl.h"
+#include "socket_ip.h"
 
 
-#ifdef HAVE_NSPR
-
-#include "mutexNsprImpl.h"
-
-#endif  // HAVE_NSPR
+TypeHandle Socket_IP::_type_handle;

+ 26 - 5
panda/src/nativenet/socket_ip.h

@@ -1,6 +1,11 @@
 #ifndef __SOCKET_IP_H__
 #ifndef __SOCKET_IP_H__
 #define __SOCKET_IP_H__
 #define __SOCKET_IP_H__
 
 
+#include "pandabase.h"
+#include "socket_portable.h"
+#include "socket_address.h"
+#include "typedObject.h"
+
 // forward declarations for friends...
 // forward declarations for friends...
 class Socket_TCP;
 class Socket_TCP;
 class Socket_UDP;
 class Socket_UDP;
@@ -26,8 +31,7 @@ class Socket_UDP_Outgoing;
 // socket_fdset
 // socket_fdset
 //
 //
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA Socket_IP
-{
+class EXPCL_PANDA Socket_IP : public TypedObject {
 public:
 public:
 PUBLISHED:
 PUBLISHED:
 
 
@@ -39,7 +43,7 @@ PUBLISHED:
     inline static int GetLastError();
     inline static int GetLastError();
     inline int SetNonBlocking();
     inline int SetNonBlocking();
     inline int SetBlocking();
     inline int SetBlocking();
-    inline bool SetReuseAddress();
+    inline bool SetReuseAddress(bool flag = true);
     inline bool Active();
     inline bool Active();
     inline int SetRecvBufferSize(int size);
     inline int SetRecvBufferSize(int size);
     inline void SetSocket(SOCKET ins);
     inline void SetSocket(SOCKET ins);
@@ -62,6 +66,23 @@ private:
     friend class Socket_UDP_Incoming;
     friend class Socket_UDP_Incoming;
     friend class Socket_UDP_Outgoing;
     friend class Socket_UDP_Outgoing;
     friend class Socket_TCP_SSL;
     friend class Socket_TCP_SSL;
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    TypedObject::init_type();
+    register_type(_type_handle, "Socket_IP",
+                  TypedObject::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -204,9 +225,9 @@ inline int Socket_IP::SetBlocking()
 // Function name :  SetReuseAddress
 // Function name :  SetReuseAddress
 // Description     :  Informs a socket to reuse IP address as needed
 // Description     :  Informs a socket to reuse IP address as needed
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-inline bool Socket_IP::SetReuseAddress()
+inline bool Socket_IP::SetReuseAddress(bool flag)
 {
 {
-    int bOption = 1;
+    int bOption = flag;
     if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&bOption, sizeof(bOption)) != 0)
     if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&bOption, sizeof(bOption)) != 0)
         return false;
         return false;
     return true;
     return true;

+ 4 - 10
panda/src/net/pprerror.h → panda/src/nativenet/socket_tcp.cxx

@@ -1,5 +1,5 @@
-// Filename: pprerror.h
-// Created by:  drose (08Feb00)
+// Filename: socket_tcp.cxx
+// Created by:  drose (01Mar07)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //
@@ -16,12 +16,6 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-#ifndef PPRERROR_H
-#define PPRERROR_H
-
-#include "pandabase.h"
-
-void pprerror(const char *format, ...);
-
-#endif
+#include "socket_tcp.h"
 
 
+TypeHandle Socket_TCP::_type_handle;

+ 23 - 3
panda/src/nativenet/socket_tcp.h

@@ -1,6 +1,9 @@
 #ifndef __SOCKET_TCP_H__
 #ifndef __SOCKET_TCP_H__
 #define __SOCKET_TCP_H__ 
 #define __SOCKET_TCP_H__ 
 
 
+#include "pandabase.h"
+#include "socket_ip.h"
+
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
 // Class : Socket_TCP
 // Class : Socket_TCP
 //
 //
@@ -15,7 +18,7 @@ public:
 PUBLISHED:
 PUBLISHED:
     inline Socket_TCP(SOCKET);
     inline Socket_TCP(SOCKET);
     inline Socket_TCP()    {   };    
     inline Socket_TCP()    {   };    
-    inline int  SetNoDelay();
+    inline int  SetNoDelay(bool flag = true);
     inline int  SetLinger(int interval_seconds = 0);
     inline int  SetLinger(int interval_seconds = 0);
     inline int  DontLinger();    
     inline int  DontLinger();    
     inline int  SetSendBufferSize(int insize);
     inline int  SetSendBufferSize(int insize);
@@ -30,6 +33,23 @@ PUBLISHED:
 public:
 public:
     inline int  SendData(const char * data, int size);
     inline int  SendData(const char * data, int size);
     inline int  RecvData(char * data, int size);
     inline int  RecvData(char * data, int size);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_IP::init_type();
+    register_type(_type_handle, "Socket_TCP",
+                  Socket_IP::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
 
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
@@ -44,9 +64,9 @@ inline Socket_TCP::Socket_TCP(SOCKET sck) : ::Socket_IP(sck)
 // Function name : SetNoDelay
 // Function name : SetNoDelay
 // Description   : Disable Nagle algorithm. Don't delay send to coalesce packets
 // Description   : Disable Nagle algorithm. Don't delay send to coalesce packets
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-inline int Socket_TCP::SetNoDelay()
+inline int Socket_TCP::SetNoDelay(bool flag)
 {
 {
-    int nodel = 1;
+    int nodel = flag;
     int ret1;
     int ret1;
     ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
     ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
     
     

+ 21 - 0
panda/src/nativenet/socket_tcp_listen.cxx

@@ -0,0 +1,21 @@
+// Filename: socket_tcp_listen.cxx
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "socket_tcp_listen.h"
+
+TypeHandle Socket_TCP_Listen::_type_handle;

+ 29 - 7
panda/src/nativenet/socket_tcp_listen.h

@@ -1,6 +1,9 @@
 #ifndef __SOCKET_TCP_LISTEN_H__
 #ifndef __SOCKET_TCP_LISTEN_H__
 #define __SOCKET_TCP_LISTEN_H__
 #define __SOCKET_TCP_LISTEN_H__
 
 
+#include "pandabase.h"
+#include "socket_ip.h"
+
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
 // Class : Socket_TCP_Listen
 // Class : Socket_TCP_Listen
 // Description : Base functionality for a TCP rendezvous socket
 // Description : Base functionality for a TCP rendezvous socket
@@ -11,29 +14,48 @@ public:
 PUBLISHED:
 PUBLISHED:
     Socket_TCP_Listen() {};
     Socket_TCP_Listen() {};
     ~Socket_TCP_Listen() {};
     ~Socket_TCP_Listen() {};
-    inline bool OpenForListen(Socket_Address & Inaddess, int backlog_size = 1024);
+    inline bool OpenForListen(const Socket_Address & Inaddess, int backlog_size = 1024);
     inline bool GetIncomingConnection(Socket_TCP & newsession, Socket_Address &address);    
     inline bool GetIncomingConnection(Socket_TCP & newsession, Socket_Address &address);    
 public:
 public:
     inline bool GetIncomingConnection(SOCKET & newsession, Socket_Address &address);
     inline bool GetIncomingConnection(SOCKET & newsession, Socket_Address &address);
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_IP::init_type();
+    register_type(_type_handle, "Socket_TCP_Listen",
+                  Socket_IP::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 // Function name : OpenForListen
 // Function name : OpenForListen
 // Description   : This function will initialize a listening Socket
 // Description   : This function will initialize a listening Socket
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-inline bool Socket_TCP_Listen::OpenForListen(Socket_Address & Inaddess, int backlog_size )
+inline bool Socket_TCP_Listen::OpenForListen(const Socket_Address & Inaddess, int backlog_size )
 {
 {
     ErrorClose();
     ErrorClose();
     _socket = DO_NEWTCP();
     _socket = DO_NEWTCP();
     
     
     SetReuseAddress();
     SetReuseAddress();
     
     
-    if (DO_BIND(_socket, &Inaddess.GetAddressInfo()) != 0)
-        return ErrorClose();
-    
-    if (DO_LISTEN(_socket, backlog_size) != 0)
-        return ErrorClose();
+    if (DO_BIND(_socket, &Inaddess.GetAddressInfo()) != 0) {
+      return ErrorClose();
+    }
     
     
+    if (DO_LISTEN(_socket, backlog_size) != 0) {
+      return ErrorClose();
+    }
+
     return true;
     return true;
 }
 }
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 7 - 8
dtool/src/dtoolbase/atomicAdjustNsprImpl.cxx → panda/src/nativenet/socket_tcp_ssl.cxx

@@ -1,5 +1,5 @@
-// Filename: atomicAdjustNsprImpl.cxx
-// Created by:  drose (09Aug02)
+// Filename: socket_tcp_ssl.cxx
+// Created by:  drose (01Mar07)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //
@@ -16,12 +16,11 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-#include "selectThreadImpl.h"
+#include "socket_tcp_ssl.h"
 
 
-#ifdef HAVE_NSPR
+#ifdef HAVE_OPENSSL
 
 
-#include "atomicAdjustNsprImpl.h"
+SSL_CTX *global_ssl_ctx;
+TypeHandle Socket_TCP_SSL::_type_handle;
 
 
-PRLock *AtomicAdjustNsprImpl::_mutex = PR_NewLock();
-
-#endif  // HAVE_NSPR
+#endif  // HAVE_OPENSSL

+ 37 - 14
panda/src/nativenet/socket_tcp_ssl.h

@@ -1,17 +1,12 @@
 #ifndef __SOCKET_TCP_SSL_H__
 #ifndef __SOCKET_TCP_SSL_H__
 #define __SOCKET_TCP_SSL_H__ 
 #define __SOCKET_TCP_SSL_H__ 
 
 
-/////////////////////////////////////////////////////////////////////
-// Class : Socket_TCP
-//
-// Description : Base functionality for a TCP connected socket
-//               This class is pretty useless by itself but it does hide some of the
-//               platform differences from machine to machine
-//
-/////////////////////////////////////////////////////////////////////
 #include "pandabase.h"
 #include "pandabase.h"
+#include "socket_ip.h"
 #include "numeric_types.h"
 #include "numeric_types.h"
 
 
+#ifdef HAVE_OPENSSL
+
 #include <openssl/rsa.h>       /* SSLeay stuff */
 #include <openssl/rsa.h>       /* SSLeay stuff */
 #include <openssl/crypto.h>
 #include <openssl/crypto.h>
 #include <openssl/x509.h>
 #include <openssl/x509.h>
@@ -19,9 +14,14 @@
 #include <openssl/ssl.h>
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <openssl/err.h>
 
 
+/////////////////////////////////////////////////////////////////////
+// Class : Socket_TCP_SSL
+//
+// Description : 
+//
+/////////////////////////////////////////////////////////////////////
 
 
-
-extern SSL_CTX *global_ssl_ctx;
+extern EXPCL_PANDA SSL_CTX *global_ssl_ctx;
 
 
 
 
 struct SSlStartup
 struct SSlStartup
@@ -47,7 +47,7 @@ struct SSlStartup
 };
 };
 
 
 
 
-class Socket_TCP_SSL : public Socket_IP
+class EXPCL_PANDA Socket_TCP_SSL : public Socket_IP
 {
 {
 public:
 public:
     
     
@@ -84,6 +84,23 @@ private:
                 _ssl = NULL;
                 _ssl = NULL;
             }
             }
         }
         }
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_IP::init_type();
+    register_type(_type_handle, "Socket_TCP_SSL",
+                  Socket_IP::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
 
 
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
@@ -101,7 +118,7 @@ inline Socket_TCP_SSL::Socket_TCP_SSL(SOCKET sck) : ::Socket_IP(sck)
         return;
         return;
     SSL_set_fd (_ssl,(int)GetSocket() );
     SSL_set_fd (_ssl,(int)GetSocket() );
 
 
-    int err =  SSL_accept(_ssl);
+    SSL_accept(_ssl);
     ERR_clear_error();
     ERR_clear_error();
 
 
 //    printf(" Ssl Accept = %d \n",err);
 //    printf(" Ssl Accept = %d \n",err);
@@ -244,7 +261,9 @@ inline bool Socket_TCP_SSL::ErrorIs_WouldBlocking(int err)
 {
 {
     if(_ssl == NULL || err >= 0)
     if(_ssl == NULL || err >= 0)
     {
     {
-   	    LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking->Called With Error numebr %d or _ssl is NULL",err);
+      nativenet_cat.warning()
+        << "Socket_TCP_SSL::ErrorIs_WouldBlocking->Called With Error number "
+        << err << " or _ssl is NULL\n";
         return false;
         return false;
     }
     }
 
 
@@ -296,9 +315,13 @@ inline void Socket_TCP_SSL::DetailErrorFormat(void)
     {
     {
         ERR_error_string_n(l, buf, sizeof( buf) );
         ERR_error_string_n(l, buf, sizeof( buf) );
         BIO_snprintf(buf2, sizeof(buf2), "***%lu:%s:%s:%d:%s\n", es, buf,file, line, (flags & ERR_TXT_STRING) ? data : "NoText");
         BIO_snprintf(buf2, sizeof(buf2), "***%lu:%s:%s:%d:%s\n", es, buf,file, line, (flags & ERR_TXT_STRING) ? data : "NoText");
-        LOGWARNING("Socket_TCP_SSL::DetailErrorFormat->[%s]",buf2);
+        nativenet_cat.warning()
+          << "Socket_TCP_SSL::DetailErrorFormat->[" << buf2 << "]\n";
     }
     }
 }
 }
+
+#endif  // HAVE_OPENSSL
+
 #endif //__SOCKET_TCP_SSL_H__
 #endif //__SOCKET_TCP_SSL_H__
 
 
 
 

+ 21 - 0
panda/src/nativenet/socket_udp.cxx

@@ -0,0 +1,21 @@
+// Filename: socket_udp.cxx
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "socket_udp.h"
+
+TypeHandle Socket_UDP::_type_handle;

+ 169 - 0
panda/src/nativenet/socket_udp.h

@@ -0,0 +1,169 @@
+// Filename: socket_udp.h
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef __SOCKET_UDP_H__
+#define __SOCKET_UDP_H__
+
+#include "socket_udp_incoming.h"
+
+/////////////////////////////////////////////////////////////////////
+// Class : Socket_UDP
+//
+// Description : Base functionality for a combination UDP Reader and
+//               Writer.  This duplicates code from
+//               Socket_UDP_Outgoing, to avoid the problems of
+//               multiple inheritance.
+/////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA Socket_UDP : public Socket_UDP_Incoming
+{
+public:
+PUBLISHED:
+    inline Socket_UDP() { }
+
+    // use this interface for a tagreted UDP connection
+    inline bool InitToAddress(const Socket_Address & address);
+public:
+    inline bool Send(const char * data, int len);
+PUBLISHED:
+    inline bool Send(const string &data);
+    // use this interface for a none tagreted UDP connection
+    inline bool InitNoAddress();
+public:
+    inline bool SendTo(const char * data, int len, const Socket_Address & address);
+PUBLISHED:
+    inline bool SendTo(const string &data, const Socket_Address & address);
+    inline bool SetToBroadCast();
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_UDP_Incoming::init_type();
+    register_type(_type_handle, "Socket_UDP",
+                  Socket_UDP_Incoming::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+//////////////////////////////////////////////////////////////
+// Function name : Socket_UDP:SetToBroadCast
+// Description     : Ask the OS to let us receive BROADCASt packets on  this port..
+// Return type  : bool
+// Argument         : void
+//////////////////////////////////////////////////////////////
+inline bool Socket_UDP::SetToBroadCast()
+{
+    int optval = 1;
+    
+    if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
+        return false;
+    return true;
+}
+////////////////////////////////////////////////////////////////////
+// Function name : Socket_UDP::InitToAddress
+// Description     : Connects the Socket to a Specified address
+//
+// Return type  : inline bool
+// Argument         : NetAddress & address
+////////////////////////////////////////////////////////////////////
+inline bool Socket_UDP::InitToAddress(const Socket_Address & address)
+{
+    if (InitNoAddress() != true)
+        return false;
+    
+    if (DO_CONNECT(_socket, &address.GetAddressInfo()) != 0)
+        return ErrorClose();
+    
+    return true;
+}
+////////////////////////////////////////////////////////////////////
+// Function name : Socket_UDP::InitNoAddress
+// Description     : This will set a udp up for targeted sends..
+//
+// Return type  : inline bool
+// Argument         : void
+////////////////////////////////////////////////////////////////////
+inline bool Socket_UDP::InitNoAddress()
+{
+    Close();
+    _socket = DO_NEWUDP();
+    if (_socket == BAD_SOCKET)
+        return false;
+    
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////
+// Function name : Socket_UDP::Send
+// Description     : Send data to connected address
+//
+// Return type  : inline bool
+// Argument         : char * data
+// Argument         : int len
+////////////////////////////////////////////////////////////////////
+inline bool Socket_UDP::Send(const char * data, int len)
+{
+  return (DO_SOCKET_WRITE(_socket, data, len) == len);
+}
+
+////////////////////////////////////////////////////////////////////
+// Function name : Socket_UDP::Send
+// Description     : Send data to connected address
+//
+// Return type  : inline bool
+// Argument         : const string &data
+////////////////////////////////////////////////////////////////////
+inline bool Socket_UDP::Send(const string &data)
+{
+  return Send(data.data(), data.size());
+}
+
+////////////////////////////////////////////////////////////////////
+// Function name : Socket_UDP::SendTo
+// Description     : Send data to specified address
+//
+// Return type  : inline bool
+// Argument         : char * data
+// Argument         : int len
+// Argument         : NetAddress & address
+////////////////////////////////////////////////////////////////////
+inline bool Socket_UDP::SendTo(const char * data, int len, const Socket_Address & address)
+{
+    return (DO_SOCKET_WRITE_TO(_socket, data, len, &address.GetAddressInfo()) == len);
+}
+
+////////////////////////////////////////////////////////////////////
+// Function name : Socket_UDP::SendTo
+// Description     : Send data to specified address
+//
+// Return type  : inline bool
+// Argument         : const string &data
+// Argument         : NetAddress & address
+////////////////////////////////////////////////////////////////////
+inline bool Socket_UDP::SendTo(const string &data, const Socket_Address & address)
+{
+  return SendTo(data.data(), data.size(), address);
+}
+
+#endif //__SOCKET_UDP_H__

+ 21 - 0
panda/src/nativenet/socket_udp_incoming.cxx

@@ -0,0 +1,21 @@
+// Filename: socket_udp_incoming.cxx
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "socket_udp_incoming.h"
+
+TypeHandle Socket_UDP_Incoming::_type_handle;

+ 29 - 6
panda/src/nativenet/socket_udp_incoming.h

@@ -1,5 +1,9 @@
 #ifndef __SOCKET_UDP_INCOMING_H__
 #ifndef __SOCKET_UDP_INCOMING_H__
 #define __SOCKET_UDP_INCOMING_H__
 #define __SOCKET_UDP_INCOMING_H__
+
+#include "pandabase.h"
+#include "socket_ip.h"
+
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
 // Class : Socket_UDP_Incoming
 // Class : Socket_UDP_Incoming
 //
 //
@@ -7,17 +11,36 @@
 //
 //
 //
 //
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
-class Socket_UDP_Incoming : public Socket_IP
+class EXPCL_PANDA Socket_UDP_Incoming : public Socket_IP
 {
 {
-public:
 PUBLISHED:
 PUBLISHED:
-    inline bool OpenForInput(Socket_Address & address);
-    inline bool OpenForInputMCast(Socket_Address & address );
+    inline Socket_UDP_Incoming() { }
+
+    inline bool OpenForInput(const Socket_Address & address);
+    inline bool OpenForInputMCast(const Socket_Address & address );
     inline bool GetPacket(char * data, int *max_len, Socket_Address & address);
     inline bool GetPacket(char * data, int *max_len, Socket_Address & address);
     inline bool SendTo(const char * data, int len, const Socket_Address & address);
     inline bool SendTo(const char * data, int len, const Socket_Address & address);
     inline bool InitNoAddress();
     inline bool InitNoAddress();
     inline bool SetToBroadCast();
     inline bool SetToBroadCast();
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_IP::init_type();
+    register_type(_type_handle, "Socket_UDP_Incoming",
+                  Socket_IP::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
+
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 // Function name : Socket_UDP_Incoming::tToBroadCast
 // Function name : Socket_UDP_Incoming::tToBroadCast
 // Description     : Flips the OS bits that allow for brodcast
 // Description     : Flips the OS bits that allow for brodcast
@@ -57,7 +80,7 @@ inline bool Socket_UDP_Incoming::InitNoAddress()
 // Return type  : bool
 // Return type  : bool
 // Argument         : NetAddress & address
 // Argument         : NetAddress & address
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-inline bool Socket_UDP_Incoming::OpenForInput(Socket_Address & address)
+inline bool Socket_UDP_Incoming::OpenForInput(const Socket_Address & address)
 {
 {
     Close();
     Close();
     _socket = DO_NEWUDP();
     _socket = DO_NEWUDP();
@@ -77,7 +100,7 @@ inline bool Socket_UDP_Incoming::OpenForInput(Socket_Address & address)
 // Return type  : bool
 // Return type  : bool
 // Argument         : NetAddress & address
 // Argument         : NetAddress & address
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-inline bool Socket_UDP_Incoming::OpenForInputMCast(Socket_Address & address)
+inline bool Socket_UDP_Incoming::OpenForInputMCast(const Socket_Address & address)
 {
 {
     Close();
     Close();
     _socket = DO_NEWUDP();
     _socket = DO_NEWUDP();

+ 21 - 0
panda/src/nativenet/socket_udp_outgoing.cxx

@@ -0,0 +1,21 @@
+// Filename: socket_udp_outgoing.cxx
+// Created by:  drose (01Mar07)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "socket_udp_outgoing.h"
+
+TypeHandle Socket_UDP_Outgoing::_type_handle;

+ 19 - 2
panda/src/nativenet/socket_udp_outgoing.h

@@ -15,7 +15,7 @@ PUBLISHED:
     inline Socket_UDP_Outgoing() { }
     inline Socket_UDP_Outgoing() { }
 
 
     // use this interface for a tagreted UDP connection
     // use this interface for a tagreted UDP connection
-    inline bool InitToAddress(Socket_Address & address);
+    inline bool InitToAddress(const Socket_Address & address);
 public:
 public:
     inline bool Send(const char * data, int len);
     inline bool Send(const char * data, int len);
 PUBLISHED:
 PUBLISHED:
@@ -27,6 +27,23 @@ public:
 PUBLISHED:
 PUBLISHED:
     inline bool SendTo(const string &data, const Socket_Address & address);
     inline bool SendTo(const string &data, const Socket_Address & address);
     inline bool SetToBroadCast();
     inline bool SetToBroadCast();
+  
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    Socket_IP::init_type();
+    register_type(_type_handle, "Socket_UDP_Outgoing",
+                  Socket_IP::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
 };
 };
 //////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////
 // Function name : Socket_UDP_Outgoing:SetToBroadCast
 // Function name : Socket_UDP_Outgoing:SetToBroadCast
@@ -49,7 +66,7 @@ inline bool Socket_UDP_Outgoing::SetToBroadCast()
 // Return type  : inline bool
 // Return type  : inline bool
 // Argument         : NetAddress & address
 // Argument         : NetAddress & address
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-inline bool Socket_UDP_Outgoing::InitToAddress(Socket_Address & address)
+inline bool Socket_UDP_Outgoing::InitToAddress(const Socket_Address & address)
 {
 {
     if (InitNoAddress() != true)
     if (InitNoAddress() != true)
         return false;
         return false;

+ 8 - 8
panda/src/net/Sources.pp

@@ -1,13 +1,13 @@
 #define OTHER_LIBS \
 #define OTHER_LIBS \
    interrogatedb:c dconfig:c dtoolconfig:m \
    interrogatedb:c dconfig:c dtoolconfig:m \
    dtoolutil:c dtoolbase:c prc:c dtool:m
    dtoolutil:c dtoolbase:c prc:c dtool:m
-#define BUILD_DIRECTORY $[and $[HAVE_NET],$[HAVE_NSPR]]
-#define USE_PACKAGES net nspr
+#define BUILD_DIRECTORY $[and $[HAVE_NET],$[WANT_NATIVE_NET]]
+#define USE_PACKAGES net
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET net
   #define TARGET net
   #define LOCAL_LIBS \
   #define LOCAL_LIBS \
-    express pandabase
+    express pandabase nativenet pipeline
 
 
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
 
 
@@ -18,7 +18,7 @@
      datagramTCPHeader.I datagramTCPHeader.h  \
      datagramTCPHeader.I datagramTCPHeader.h  \
      datagramUDPHeader.I datagramUDPHeader.h  \
      datagramUDPHeader.I datagramUDPHeader.h  \
      netAddress.h netDatagram.I netDatagram.h  \
      netAddress.h netDatagram.I netDatagram.h  \
-     pprerror.h queuedConnectionListener.I  \
+     queuedConnectionListener.I  \
      queuedConnectionListener.h queuedConnectionManager.h  \
      queuedConnectionListener.h queuedConnectionManager.h  \
      queuedConnectionReader.h recentConnectionReader.h \
      queuedConnectionReader.h recentConnectionReader.h \
      queuedReturn.h queuedReturn.I
      queuedReturn.h queuedReturn.I
@@ -28,7 +28,7 @@
      connectionManager.cxx connectionReader.cxx  \
      connectionManager.cxx connectionReader.cxx  \
      connectionWriter.cxx datagramQueue.cxx datagramTCPHeader.cxx  \
      connectionWriter.cxx datagramQueue.cxx datagramTCPHeader.cxx  \
      datagramUDPHeader.cxx netAddress.cxx netDatagram.cxx  \
      datagramUDPHeader.cxx netAddress.cxx netDatagram.cxx  \
-     pprerror.cxx queuedConnectionListener.cxx  \
+     queuedConnectionListener.cxx  \
      queuedConnectionManager.cxx queuedConnectionReader.cxx  \
      queuedConnectionManager.cxx queuedConnectionReader.cxx  \
      recentConnectionReader.cxx 
      recentConnectionReader.cxx 
 
 
@@ -38,7 +38,7 @@
     datagramTCPHeader.I datagramTCPHeader.h \
     datagramTCPHeader.I datagramTCPHeader.h \
     datagramUDPHeader.I datagramUDPHeader.h \
     datagramUDPHeader.I datagramUDPHeader.h \
     netAddress.h netDatagram.I \
     netAddress.h netDatagram.I \
-    netDatagram.h pprerror.h queuedConnectionListener.I \
+    netDatagram.h queuedConnectionListener.I \
     queuedConnectionListener.h queuedConnectionManager.h \
     queuedConnectionListener.h queuedConnectionManager.h \
     queuedConnectionReader.h queuedReturn.I queuedReturn.h \
     queuedConnectionReader.h queuedReturn.I queuedReturn.h \
     recentConnectionReader.h
     recentConnectionReader.h
@@ -59,7 +59,7 @@
 
 
 #begin test_bin_target
 #begin test_bin_target
   #define TARGET test_spam_client
   #define TARGET test_spam_client
-  #define LOCAL_LIBS net
+  #define LOCAL_LIBS net putil
   #define OTHER_LIBS $[OTHER_LIBS] pystub
   #define OTHER_LIBS $[OTHER_LIBS] pystub
 
 
   #define SOURCES \
   #define SOURCES \
@@ -69,7 +69,7 @@
 
 
 #begin test_bin_target
 #begin test_bin_target
   #define TARGET test_spam_server
   #define TARGET test_spam_server
-  #define LOCAL_LIBS net
+  #define LOCAL_LIBS net putil
   #define OTHER_LIBS $[OTHER_LIBS] pystub
   #define OTHER_LIBS $[OTHER_LIBS] pystub
 
 
   #define SOURCES \
   #define SOURCES \

+ 83 - 136
panda/src/net/connection.cxx

@@ -21,11 +21,15 @@
 #include "netDatagram.h"
 #include "netDatagram.h"
 #include "datagramTCPHeader.h"
 #include "datagramTCPHeader.h"
 #include "datagramUDPHeader.h"
 #include "datagramUDPHeader.h"
-#include "pprerror.h"
 #include "config_net.h"
 #include "config_net.h"
 #include "config_express.h" // for collect_tcp
 #include "config_express.h" // for collect_tcp
 #include "trueClock.h"
 #include "trueClock.h"
 #include "pnotify.h"
 #include "pnotify.h"
+#include "mutexHolder.h"
+#include "socket_ip.h"
+#include "socket_tcp.h"
+#include "socket_udp.h"
+#include "dcast.h"
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -37,11 +41,10 @@
 //               connection.
 //               connection.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 Connection::
 Connection::
-Connection(ConnectionManager *manager, PRFileDesc *socket) :
+Connection(ConnectionManager *manager, Socket_IP *socket) :
   _manager(manager),
   _manager(manager),
   _socket(socket)
   _socket(socket)
 {
 {
-  _write_mutex = PR_NewLock();
   _collect_tcp = collect_tcp;
   _collect_tcp = collect_tcp;
   _collect_tcp_interval = collect_tcp_interval;
   _collect_tcp_interval = collect_tcp_interval;
   _queued_data_start = 0.0;
   _queued_data_start = 0.0;
@@ -58,16 +61,12 @@ Connection::
   net_cat.info()
   net_cat.info()
     << "Deleting connection " << (void *)this << "\n";
     << "Deleting connection " << (void *)this << "\n";
 
 
-  if (_socket != (PRFileDesc *)NULL) {
+  if (_socket != (Socket_IP *)NULL) {
     flush();
     flush();
 
 
-    PRStatus result = PR_Close(_socket);
-    if (result != PR_SUCCESS) {
-      pprerror("PR_Close");
-    }
+    _socket->Close();
+    delete _socket;
   }
   }
-
-  PR_DestroyLock(_write_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -78,11 +77,7 @@ Connection::
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 NetAddress Connection::
 NetAddress Connection::
 get_address() const {
 get_address() const {
-  PRNetAddr addr;
-  if (PR_GetSockName(_socket, &addr) != PR_SUCCESS) {
-    pprerror("PR_GetSockName");
-  }
-
+  Socket_Address addr = _socket->GetPeerName();
   return NetAddress(addr);
   return NetAddress(addr);
 }
 }
 
 
@@ -100,10 +95,10 @@ get_manager() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Connection::get_socket
 //     Function: Connection::get_socket
 //       Access: Published
 //       Access: Published
-//  Description: Returns the internal NSPR pointer that defines the
+//  Description: Returns the internal Socket_IP that defines the
 //               connection.
 //               connection.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-PRFileDesc *Connection::
+Socket_IP *Connection::
 get_socket() const {
 get_socket() const {
   return _socket;
   return _socket;
 }
 }
@@ -182,7 +177,7 @@ get_collect_tcp_interval() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Connection::
 bool Connection::
 consider_flush() {
 consider_flush() {
-  PR_Lock(_write_mutex);
+  MutexHolder holder(_write_mutex);
 
 
   if (!_collect_tcp) {
   if (!_collect_tcp) {
     return do_flush();
     return do_flush();
@@ -197,7 +192,6 @@ consider_flush() {
     }
     }
   }
   }
 
 
-  PR_Unlock(_write_mutex);
   return true;
   return true;
 }
 }
 
 
@@ -210,7 +204,7 @@ consider_flush() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Connection::
 bool Connection::
 flush() {
 flush() {
-  PR_Lock(_write_mutex);
+  MutexHolder holder(_write_mutex);
   return do_flush();
   return do_flush();
 }
 }
 
 
@@ -221,10 +215,11 @@ flush() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_nonblock(bool flag) {
 set_nonblock(bool flag) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_Nonblocking;
-  data.value.non_blocking = flag;
-  PR_SetSocketOption(_socket, &data);
+  if (flag) {
+    _socket->SetNonBlocking();
+  } else {
+    _socket->SetBlocking();
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -241,11 +236,14 @@ set_nonblock(bool flag) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_linger(bool flag, double time) {
 set_linger(bool flag, double time) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_Linger;
-  data.value.linger.polarity = flag;
-  data.value.linger.linger = PRIntervalTime(time * PR_INTERVAL_MIN);
-  PR_SetSocketOption(_socket, &data);
+  Socket_TCP *tcp;
+  DCAST_INTO_V(tcp, _socket);
+
+  if (flag) {
+    tcp->SetLinger((int)time);
+  } else {
+    tcp->DontLinger();
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -255,10 +253,7 @@ set_linger(bool flag, double time) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_reuse_addr(bool flag) {
 set_reuse_addr(bool flag) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_Reuseaddr;
-  data.value.reuse_addr = flag;
-  PR_SetSocketOption(_socket, &data);
+  _socket->SetReuseAddress(flag);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -269,10 +264,7 @@ set_reuse_addr(bool flag) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_keep_alive(bool flag) {
 set_keep_alive(bool flag) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_Keepalive;
-  data.value.keep_alive = flag;
-  PR_SetSocketOption(_socket, &data);
+  // TODO.
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -282,10 +274,7 @@ set_keep_alive(bool flag) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_recv_buffer_size(int size) {
 set_recv_buffer_size(int size) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_RecvBufferSize;
-  data.value.recv_buffer_size = size;
-  PR_SetSocketOption(_socket, &data);
+  _socket->SetRecvBufferSize(size);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -295,10 +284,10 @@ set_recv_buffer_size(int size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_send_buffer_size(int size) {
 set_send_buffer_size(int size) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_SendBufferSize;
-  data.value.send_buffer_size = size;
-  PR_SetSocketOption(_socket, &data);
+  Socket_TCP *tcp;
+  DCAST_INTO_V(tcp, _socket);
+
+  tcp->SetSendBufferSize(size);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -308,10 +297,7 @@ set_send_buffer_size(int size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_ip_time_to_live(int ttl) {
 set_ip_time_to_live(int ttl) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_IpTimeToLive;
-  data.value.ip_ttl = ttl;
-  PR_SetSocketOption(_socket, &data);
+  // TODO.
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -321,10 +307,7 @@ set_ip_time_to_live(int ttl) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_ip_type_of_service(int tos) {
 set_ip_type_of_service(int tos) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_IpTypeOfService;
-  data.value.tos = tos;
-  PR_SetSocketOption(_socket, &data);
+  // TODO.
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -335,10 +318,10 @@ set_ip_type_of_service(int tos) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_no_delay(bool flag) {
 set_no_delay(bool flag) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_NoDelay;
-  data.value.no_delay = flag;
-  PR_SetSocketOption(_socket, &data);
+  Socket_TCP *tcp;
+  DCAST_INTO_V(tcp, _socket);
+
+  tcp->SetNoDelay(flag);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -348,10 +331,7 @@ set_no_delay(bool flag) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Connection::
 void Connection::
 set_max_segment(int size) {
 set_max_segment(int size) {
-  PRSocketOptionData data;
-  data.option = PR_SockOpt_MaxSegment;
-  data.value.max_segment = size;
-  PR_SetSocketOption(_socket, &data);
+  // TODO.
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -365,37 +345,34 @@ set_max_segment(int size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Connection::
 bool Connection::
 send_datagram(const NetDatagram &datagram, int tcp_header_size) {
 send_datagram(const NetDatagram &datagram, int tcp_header_size) {
-  nassertr(_socket != (PRFileDesc *)NULL, false);
+  nassertr(_socket != (Socket_IP *)NULL, false);
 
 
-  if (PR_GetDescType(_socket) == PR_DESC_SOCKET_UDP) {
+  if (_socket->is_exact_type(Socket_UDP::get_class_type())) {
     // We have to send UDP right away.
     // We have to send UDP right away.
-    PR_Lock(_write_mutex);
+    Socket_UDP *udp;
+    DCAST_INTO_R(udp, _socket, false);
+
+    MutexHolder holder(_write_mutex);
     DatagramUDPHeader header(datagram);
     DatagramUDPHeader header(datagram);
     string data;
     string data;
     data += header.get_header();
     data += header.get_header();
     data += datagram.get_message();
     data += datagram.get_message();
-
-    PRInt32 bytes_to_send = data.length();
-    PRInt32 result;
-    result = PR_SendTo(_socket,
-                       data.data(), bytes_to_send,
-                       0,
-                       datagram.get_address().get_addr(),
-                       PR_INTERVAL_NO_TIMEOUT);
-    PRErrorCode errcode = PR_GetError();
-
+    
+    int bytes_to_send = data.length();
+    bool okflag = udp->SendTo(data, datagram.get_address().get_addr());
+    
     if (net_cat.is_debug()) {
     if (net_cat.is_debug()) {
       header.verify_datagram(datagram);
       header.verify_datagram(datagram);
     }
     }
-
+    
     if (net_cat.is_spam()) {
     if (net_cat.is_spam()) {
       net_cat.spam()
       net_cat.spam()
         << "Sending UDP datagram with " 
         << "Sending UDP datagram with " 
-        << bytes_to_send << " bytes to " << (void *)this << "\n";
+        << bytes_to_send << " bytes to " << (void *)this 
+        << ", ok = " << okflag << "\n";
     }
     }
-
-    PR_Unlock(_write_mutex);
-    return check_send_error(result, errcode, bytes_to_send);
+      
+    return check_send_error(okflag);
   }
   }
 
 
   // We might queue up TCP packets for later sending.
   // We might queue up TCP packets for later sending.
@@ -409,7 +386,7 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
 
 
   DatagramTCPHeader header(datagram, tcp_header_size);
   DatagramTCPHeader header(datagram, tcp_header_size);
 
 
-  PR_Lock(_write_mutex);
+  MutexHolder holder(_write_mutex);
   _queued_data += header.get_header();
   _queued_data += header.get_header();
   _queued_data += datagram.get_message();
   _queued_data += datagram.get_message();
   _queued_count++;
   _queued_count++;
@@ -423,7 +400,6 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
     return do_flush();
     return do_flush();
   }
   }
 
 
-  PR_Unlock(_write_mutex);
   return true;
   return true;
 }
 }
 
 
@@ -436,36 +412,30 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Connection::
 bool Connection::
 send_raw_datagram(const NetDatagram &datagram) {
 send_raw_datagram(const NetDatagram &datagram) {
-  nassertr(_socket != (PRFileDesc *)NULL, false);
+  nassertr(_socket != (Socket_IP *)NULL, false);
 
 
-  if (PR_GetDescType(_socket) == PR_DESC_SOCKET_UDP) {
+  if (_socket->is_exact_type(Socket_UDP::get_class_type())) {
     // We have to send UDP right away.
     // We have to send UDP right away.
+    Socket_UDP *udp;
+    DCAST_INTO_R(udp, _socket, false);
 
 
     string data = datagram.get_message();
     string data = datagram.get_message();
-    PRInt32 bytes_to_send = data.length();
 
 
+    MutexHolder holder(_write_mutex);
+    bool okflag = udp->SendTo(data, datagram.get_address().get_addr());
+    
     if (net_cat.is_spam()) {
     if (net_cat.is_spam()) {
       net_cat.spam()
       net_cat.spam()
         << "Sending UDP datagram with " 
         << "Sending UDP datagram with " 
-        << bytes_to_send << " bytes to " << (void *)this << "\n";
+        << data.size() << " bytes to " << (void *)this 
+        << ", ok = " << okflag << "\n";
     }
     }
 
 
-    PR_Lock(_write_mutex);
-    PRInt32 result;
-    result = PR_SendTo(_socket,
-                       data.data(), bytes_to_send,
-                       0,
-                       datagram.get_address().get_addr(),
-                       PR_INTERVAL_NO_TIMEOUT);
-    PRErrorCode errcode = PR_GetError();
-
-    PR_Unlock(_write_mutex);
-    return check_send_error(result, errcode, bytes_to_send);
+    return check_send_error(okflag);
   }
   }
 
 
   // We might queue up TCP packets for later sending.
   // We might queue up TCP packets for later sending.
-
-  PR_Lock(_write_mutex);
+  MutexHolder holder(_write_mutex);
   _queued_data += datagram.get_message();
   _queued_data += datagram.get_message();
   _queued_count++;
   _queued_count++;
 
 
@@ -474,7 +444,6 @@ send_raw_datagram(const NetDatagram &datagram) {
     return do_flush();
     return do_flush();
   }
   }
 
 
-  PR_Unlock(_write_mutex);
   return true;
   return true;
 }
 }
 
 
@@ -482,70 +451,48 @@ send_raw_datagram(const NetDatagram &datagram) {
 //     Function: Connection::do_flush
 //     Function: Connection::do_flush
 //       Access: Private
 //       Access: Private
 //  Description: The private implementation of flush(), this assumes
 //  Description: The private implementation of flush(), this assumes
-//               the _write_mutex has already been locked on entry.
-//               It will be unlocked on return.
+//               the _write_mutex is already held.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Connection::
 bool Connection::
 do_flush() {
 do_flush() {
-  PRInt32 bytes_to_send = _queued_data.length();
-  if (bytes_to_send == 0) {
+  if (_queued_data.empty()) {
     _queued_count = 0;
     _queued_count = 0;
     _queued_data_start = TrueClock::get_global_ptr()->get_short_time();
     _queued_data_start = TrueClock::get_global_ptr()->get_short_time();
-    PR_Unlock(_write_mutex);
     return true;
     return true;
   }
   }
 
 
   if (net_cat.is_spam()) {
   if (net_cat.is_spam()) {
     net_cat.spam()
     net_cat.spam()
       << "Sending " << _queued_count << " TCP datagram(s) with " 
       << "Sending " << _queued_count << " TCP datagram(s) with " 
-      << bytes_to_send << " total bytes to " << (void *)this << "\n";
+      << _queued_data.length() << " total bytes to " << (void *)this << "\n";
   }
   }
 
 
-  PRInt32 result;
-  result = PR_Send(_socket,
-                   _queued_data.data(), bytes_to_send,
-                   0,
-                   PR_INTERVAL_NO_TIMEOUT);
-  PRErrorCode errcode = PR_GetError();
+  Socket_TCP *tcp;
+  DCAST_INTO_R(tcp, _socket, false);
+
+  bool okflag = (tcp->SendData(_queued_data) == _queued_data.size());
 
 
   _queued_data = string();
   _queued_data = string();
   _queued_count = 0;
   _queued_count = 0;
   _queued_data_start = TrueClock::get_global_ptr()->get_short_time();
   _queued_data_start = TrueClock::get_global_ptr()->get_short_time();
 
 
-  PR_Unlock(_write_mutex);
-
-  return check_send_error(result, errcode, bytes_to_send);
+  return check_send_error(okflag);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Connection::check_send_error
 //     Function: Connection::check_send_error
 //       Access: Private
 //       Access: Private
-//  Description: Checks the return value of a PR_Send() or PR_SendTo()
+//  Description: Checks the return value of a Send() or SendTo()
 //               call.
 //               call.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Connection::
 bool Connection::
-check_send_error(PRInt32 result, PRErrorCode errcode, PRInt32 bytes_to_send) {
-  if (result < 0) {
-    if (errcode == PR_CONNECT_RESET_ERROR
-#ifdef PR_SOCKET_SHUTDOWN_ERROR
-        || errcode == PR_SOCKET_SHUTDOWN_ERROR
-        || errcode == PR_CONNECT_ABORTED_ERROR
-#endif
-        ) {
-      // The connection has been reset; tell our manager about it
-      // and ignore it.
-      if (_manager != (ConnectionManager *)NULL) {
-        _manager->connection_reset(this, errcode);
-      }
-
-    } else if (errcode != PR_PENDING_INTERRUPT_ERROR) {
-      pprerror("PR_SendTo");
+check_send_error(bool okflag) {
+  if (!okflag) {
+    // Assume any error means the connection has been reset; tell
+    // our manager about it and ignore it.
+    if (_manager != (ConnectionManager *)NULL) {
+      _manager->connection_reset(this, okflag);
     }
     }
-
-    return false;
-
-  } else if (result != bytes_to_send) {
-    net_cat.error() << "Not enough bytes sent to socket.\n";
     return false;
     return false;
   }
   }
 
 

+ 7 - 9
panda/src/net/connection.h

@@ -22,11 +22,9 @@
 #include "pandabase.h"
 #include "pandabase.h"
 #include "referenceCount.h"
 #include "referenceCount.h"
 #include "netAddress.h"
 #include "netAddress.h"
+#include "pmutex.h"
 
 
-#include <prio.h>
-#include <prlock.h>
-#include <prerror.h>
-
+class Socket_IP;
 class ConnectionManager;
 class ConnectionManager;
 class NetDatagram;
 class NetDatagram;
 
 
@@ -37,13 +35,13 @@ class NetDatagram;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDA Connection : public ReferenceCount {
 class EXPCL_PANDA Connection : public ReferenceCount {
 PUBLISHED:
 PUBLISHED:
-  Connection(ConnectionManager *manager, PRFileDesc *socket);
+  Connection(ConnectionManager *manager, Socket_IP *socket);
   ~Connection();
   ~Connection();
 
 
   NetAddress get_address() const;
   NetAddress get_address() const;
   ConnectionManager *get_manager() const;
   ConnectionManager *get_manager() const;
 
 
-  PRFileDesc *get_socket() const;
+  Socket_IP *get_socket() const;
 
 
   void set_collect_tcp(bool collect_tcp);
   void set_collect_tcp(bool collect_tcp);
   bool get_collect_tcp() const;
   bool get_collect_tcp() const;
@@ -69,11 +67,11 @@ private:
   bool send_datagram(const NetDatagram &datagram, int tcp_header_size);
   bool send_datagram(const NetDatagram &datagram, int tcp_header_size);
   bool send_raw_datagram(const NetDatagram &datagram);
   bool send_raw_datagram(const NetDatagram &datagram);
   bool do_flush();
   bool do_flush();
-  bool check_send_error(PRInt32 result, PRErrorCode errcode, PRInt32 bytes_to_send);
+  bool check_send_error(bool okflag);
 
 
   ConnectionManager *_manager;
   ConnectionManager *_manager;
-  PRFileDesc *_socket;
-  PRLock *_write_mutex;
+  Socket_IP *_socket;
+  Mutex _write_mutex;
 
 
   bool _collect_tcp;
   bool _collect_tcp;
   double _collect_tcp_interval;
   double _collect_tcp_interval;

+ 10 - 8
panda/src/net/connectionListener.cxx

@@ -20,8 +20,8 @@
 #include "connection.h"
 #include "connection.h"
 #include "connectionManager.h"
 #include "connectionManager.h"
 #include "netAddress.h"
 #include "netAddress.h"
-#include "pprerror.h"
 #include "config_net.h"
 #include "config_net.h"
+#include "socket_tcp_listen.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionListener::Constructor
 //     Function: ConnectionListener::Constructor
@@ -56,13 +56,15 @@ receive_datagram(const NetDatagram &) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionListener::
 void ConnectionListener::
 process_incoming_data(SocketInfo *sinfo) {
 process_incoming_data(SocketInfo *sinfo) {
-  PRNetAddr addr;
+  Socket_TCP_Listen *socket;
+  DCAST_INTO_V(socket, sinfo->get_socket());
 
 
-  PRFileDesc *socket =
-    PR_Accept(sinfo->get_socket(), &addr, PR_INTERVAL_NO_TIMEOUT);
-
-  if (socket == (PRFileDesc *)NULL) {
-    pprerror("PR_Accept");
+  Socket_Address addr;
+  Socket_TCP *session = new Socket_TCP;
+  if (!socket->GetIncomingConnection(*session, addr)) {
+    net_cat.error()
+      << "Error when accepting new connection.\n";
+    delete session;
 
 
   } else {
   } else {
     NetAddress net_addr(addr);
     NetAddress net_addr(addr);
@@ -71,7 +73,7 @@ process_incoming_data(SocketInfo *sinfo) {
       << " on port " << sinfo->_connection->get_address().get_port()
       << " on port " << sinfo->_connection->get_address().get_port()
       << "\n";
       << "\n";
 
 
-    PT(Connection) new_connection = new Connection(_manager, socket);
+    PT(Connection) new_connection = new Connection(_manager, session);
     if (_manager != (ConnectionManager *)NULL) {
     if (_manager != (ConnectionManager *)NULL) {
       _manager->new_connection(new_connection);
       _manager->new_connection(new_connection);
     }
     }

+ 65 - 132
panda/src/net/connectionManager.cxx

@@ -21,10 +21,8 @@
 #include "connectionReader.h"
 #include "connectionReader.h"
 #include "connectionWriter.h"
 #include "connectionWriter.h"
 #include "netAddress.h"
 #include "netAddress.h"
-#include "pprerror.h"
 #include "config_net.h"
 #include "config_net.h"
-
-#include <prerror.h>
+#include "mutexHolder.h"
 
 
 #ifdef WIN32_VC
 #ifdef WIN32_VC
 #include <winsock.h>  // For gethostname()
 #include <winsock.h>  // For gethostname()
@@ -37,7 +35,6 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 ConnectionManager::
 ConnectionManager::
 ConnectionManager() {
 ConnectionManager() {
-  _set_mutex = PR_NewLock();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -56,8 +53,6 @@ ConnectionManager::
   for (wi = _writers.begin(); wi != _writers.end(); ++wi) {
   for (wi = _writers.begin(); wi != _writers.end(); ++wi) {
     (*wi)->clear_manager();
     (*wi)->clear_manager();
   }
   }
-
-  PR_DestroyLock(_set_mutex);
 }
 }
 
 
 
 
@@ -65,41 +60,42 @@ ConnectionManager::
 //     Function: ConnectionManager::open_UDP_connection
 //     Function: ConnectionManager::open_UDP_connection
 //       Access: Public
 //       Access: Public
 //  Description: Opens a socket for sending and/or receiving UDP
 //  Description: Opens a socket for sending and/or receiving UDP
-//               packets.  If the port number is negative, it will not
-//               be bound to a socket; this is generally a pointless
-//               thing to do.  If the port number is zero, a random
-//               socket will be chosen.  Otherwise, the specified
-//               port number is used.  Normally, you don't care what
-//               port a UDP connection is opened on, so you should use
-//               the default value of zero.
+//               packets.  If the port number is greater than zero,
+//               the UDP connection will be opened for listening on
+//               the indicated port; otherwise, it will be useful only
+//               for sending.
 //
 //
 //               Use a ConnectionReader and ConnectionWriter to handle
 //               Use a ConnectionReader and ConnectionWriter to handle
 //               the actual communication.
 //               the actual communication.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(Connection) ConnectionManager::
 PT(Connection) ConnectionManager::
 open_UDP_connection(int port) {
 open_UDP_connection(int port) {
-  NetAddress address;
-  address.set_any(port);
-
-  PRFileDesc *socket = PR_NewUDPSocket();
-  if (socket == (PRFileDesc *)NULL) {
-    pprerror("PR_NewUDPSocket");
-    return PT(Connection)();
-  }
-
-  if (port >= 0) {
-    PRStatus result = PR_Bind(socket, address.get_addr());
-    if (result != PR_SUCCESS) {
-      pprerror("PR_Bind");
-      PR_Close(socket);
+  Socket_UDP *socket = new Socket_UDP;
+
+  if (port > 0) {
+    NetAddress address;
+    address.set_any(port);
+    
+    if (!socket->OpenForInput(address.get_addr())) {
+      net_cat.error()
+        << "Unable to bind to port " << port << " for UDP.\n";
+      delete socket;
       return PT(Connection)();
       return PT(Connection)();
     }
     }
 
 
     net_cat.info()
     net_cat.info()
       << "Creating UDP connection for port " << port << "\n";
       << "Creating UDP connection for port " << port << "\n";
+
   } else {
   } else {
+    if (!socket->InitNoAddress()) {
+      net_cat.error()
+        << "Unable to initialize outgoing UDP.\n";
+      delete socket;
+      return PT(Connection)();
+    }
+
     net_cat.info()
     net_cat.info()
-      << "Creating UDP connection\n";
+      << "Creating outgoing UDP connection\n";
   }
   }
 
 
   PT(Connection) connection = new Connection(this, socket);
   PT(Connection) connection = new Connection(this, socket);
@@ -125,27 +121,12 @@ open_TCP_server_rendezvous(int port, int backlog) {
   NetAddress address;
   NetAddress address;
   address.set_any(port);
   address.set_any(port);
 
 
-  PRFileDesc *socket = PR_NewTCPSocket();
-  if (socket == (PRFileDesc *)NULL) {
-    pprerror("PR_NewTCPSocket");
-    return PT(Connection)();
-  }
-
-  PRStatus result = PR_Bind(socket, address.get_addr());
-  if (result != PR_SUCCESS) {
-    pprerror("PR_Bind");
-    net_cat.info()
-      << "Unable to bind to port " << port << " for TCP.\n";
-    PR_Close(socket);
-    return PT(Connection)();
-  }
-
-  result = PR_Listen(socket, backlog);
-  if (result != PR_SUCCESS) {
-    pprerror("PR_Listen");
+  Socket_TCP_Listen *socket = new Socket_TCP_Listen;
+  bool okflag = socket->OpenForListen(address.get_addr(), backlog);
+  if (!okflag) {
     net_cat.info()
     net_cat.info()
       << "Unable to listen to port " << port << " for TCP.\n";
       << "Unable to listen to port " << port << " for TCP.\n";
-    PR_Close(socket);
+    delete socket;
     return PT(Connection)();
     return PT(Connection)();
   }
   }
 
 
@@ -167,22 +148,13 @@ open_TCP_server_rendezvous(int port, int backlog) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(Connection) ConnectionManager::
 PT(Connection) ConnectionManager::
 open_TCP_client_connection(const NetAddress &address, int timeout_ms) {
 open_TCP_client_connection(const NetAddress &address, int timeout_ms) {
-  PRFileDesc *socket = PR_NewTCPSocket();
-  if (socket == (PRFileDesc *)NULL) {
-    pprerror("PR_NewTCPSocket");
-    return PT(Connection)();
-  }
-
-  PRStatus result = PR_Connect(socket, address.get_addr(),
-                               PR_MillisecondsToInterval(timeout_ms));
-  if (result != PR_SUCCESS) {
-    if (PR_GetError() != PR_CONNECT_RESET_ERROR) {
-      pprerror("PR_Connect");
-    }
-    net_cat.info()
+  Socket_TCP *socket = new Socket_TCP;
+  bool okflag = socket->ActiveOpen(address.get_addr());
+  if (!okflag) {
+    net_cat.error()
       << "Unable to open TCP connection to server "
       << "Unable to open TCP connection to server "
       << address.get_ip_string() << " on port " << address.get_port() << "\n";
       << address.get_ip_string() << " on port " << address.get_port() << "\n";
-    PR_Close(socket);
+    delete socket;
     return PT(Connection)();
     return PT(Connection)();
   }
   }
 
 
@@ -199,7 +171,7 @@ open_TCP_client_connection(const NetAddress &address, int timeout_ms) {
 //     Function: ConnectionManager::open_TCP_client_connection
 //     Function: ConnectionManager::open_TCP_client_connection
 //       Access: Public
 //       Access: Public
 //  Description: This is a shorthand version of the function to
 //  Description: This is a shorthand version of the function to
-//               directly establish communcations to a named host and
+//               directly establish communications to a named host and
 //               port.
 //               port.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT(Connection) ConnectionManager::
 PT(Connection) ConnectionManager::
@@ -238,41 +210,32 @@ close_connection(const PT(Connection) &connection) {
     connection->flush();
     connection->flush();
   }
   }
 
 
-  PR_Lock(_set_mutex);
-  Connections::iterator ci = _connections.find(connection);
-  if (ci == _connections.end()) {
-    // Already closed, or not part of this ConnectionManager.
-    PR_Unlock(_set_mutex);
-    return false;
-  }
-  _connections.erase(ci);
-
-  Readers::iterator ri;
-  for (ri = _readers.begin(); ri != _readers.end(); ++ri) {
-    (*ri)->remove_connection(connection);
+  {
+    MutexHolder holder(_set_mutex);
+    Connections::iterator ci = _connections.find(connection);
+    if (ci == _connections.end()) {
+      // Already closed, or not part of this ConnectionManager.
+      return false;
+    }
+    _connections.erase(ci);
+    
+    Readers::iterator ri;
+    for (ri = _readers.begin(); ri != _readers.end(); ++ri) {
+      (*ri)->remove_connection(connection);
+    }
   }
   }
-  PR_Unlock(_set_mutex);
-
-  PRFileDesc *socket = connection->get_socket();
 
 
-  if (PR_GetDescType(socket) == PR_DESC_SOCKET_TCP) {
-    // We can't *actually* close the connection right now, because
-    // there might be outstanding pointers to it.  But we can at least
-    // shut it down.  It will be eventually closed when all the
-    // pointers let go.
+  Socket_IP *socket = connection->get_socket();
 
 
-    net_cat.info()
-      << "Shutting down connection " << (void *)connection
-      << " locally.\n";
-
-    PRStatus result = PR_Shutdown(socket, PR_SHUTDOWN_BOTH);
-    if (result != PR_SUCCESS) {
-      PRErrorCode errcode = PR_GetError();
-      if (errcode != PR_NOT_CONNECTED_ERROR) {
-        pprerror("PR_Shutdown");
-      }
-    }
-  }
+  // We can't *actually* close the connection right now, because
+  // there might be outstanding pointers to it.  But we can at least
+  // shut it down.  It will be eventually closed when all the
+  // pointers let go.
+  
+  net_cat.info()
+    << "Shutting down connection " << (void *)connection
+    << " locally.\n";
+  socket->Close();
 
 
   return true;
   return true;
 }
 }
@@ -305,9 +268,8 @@ get_host_name() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionManager::
 void ConnectionManager::
 new_connection(const PT(Connection) &connection) {
 new_connection(const PT(Connection) &connection) {
-  PR_Lock(_set_mutex);
+  MutexHolder holder(_set_mutex);
   _connections.insert(connection);
   _connections.insert(connection);
-  PR_Unlock(_set_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -320,9 +282,9 @@ new_connection(const PT(Connection) &connection) {
 //               been reset.
 //               been reset.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionManager::
 void ConnectionManager::
-connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
+connection_reset(const PT(Connection) &connection, bool okflag) {
   if (net_cat.is_info()) {
   if (net_cat.is_info()) {
-    if (errcode == 0) {
+    if (okflag) {
       net_cat.info()
       net_cat.info()
         << "Connection " << (void *)connection
         << "Connection " << (void *)connection
         << " was closed normally by the other end";
         << " was closed normally by the other end";
@@ -330,33 +292,8 @@ connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
     } else {
     } else {
       net_cat.info()
       net_cat.info()
         << "Lost connection " << (void *)connection
         << "Lost connection " << (void *)connection
-        << " unexpectedly: ";
-
-      switch (errcode) {
-      case PR_CONNECT_RESET_ERROR:
-        net_cat.info(false)
-          << "connection reset";
-        break;
-        
-#ifdef PR_SOCKET_SHUTDOWN_ERROR
-      case PR_SOCKET_SHUTDOWN_ERROR:
-        net_cat.info(false)
-          << "socket shutdown";
-        break;
-        
-      case PR_CONNECT_ABORTED_ERROR:
-        net_cat.info(false)
-          << "connection aborted";
-        break;
-#endif
-
-      default:
-        net_cat.info(false)
-          << "NSPR error code " << errcode;
-      }
+        << " unexpectedly\n";
     }
     }
-    net_cat.info(false)
-      << " (os error = " << PR_GetOSError() << ").\n";
   }
   }
 
 
   // Turns out we do need to explicitly mark the connection as closed
   // Turns out we do need to explicitly mark the connection as closed
@@ -374,9 +311,8 @@ connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionManager::
 void ConnectionManager::
 add_reader(ConnectionReader *reader) {
 add_reader(ConnectionReader *reader) {
-  PR_Lock(_set_mutex);
+  MutexHolder holder(_set_mutex);
   _readers.insert(reader);
   _readers.insert(reader);
-  PR_Unlock(_set_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -387,9 +323,8 @@ add_reader(ConnectionReader *reader) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionManager::
 void ConnectionManager::
 remove_reader(ConnectionReader *reader) {
 remove_reader(ConnectionReader *reader) {
-  PR_Lock(_set_mutex);
+  MutexHolder holder(_set_mutex);
   _readers.erase(reader);
   _readers.erase(reader);
-  PR_Unlock(_set_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -400,9 +335,8 @@ remove_reader(ConnectionReader *reader) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionManager::
 void ConnectionManager::
 add_writer(ConnectionWriter *writer) {
 add_writer(ConnectionWriter *writer) {
-  PR_Lock(_set_mutex);
+  MutexHolder holder(_set_mutex);
   _writers.insert(writer);
   _writers.insert(writer);
-  PR_Unlock(_set_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -413,7 +347,6 @@ add_writer(ConnectionWriter *writer) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionManager::
 void ConnectionManager::
 remove_writer(ConnectionWriter *writer) {
 remove_writer(ConnectionWriter *writer) {
-  PR_Lock(_set_mutex);
+  MutexHolder holder(_set_mutex);
   _writers.erase(writer);
   _writers.erase(writer);
-  PR_Unlock(_set_mutex);
 }
 }

+ 3 - 5
panda/src/net/connectionManager.h

@@ -25,9 +25,7 @@
 #include "connection.h"
 #include "connection.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
 #include "pset.h"
 #include "pset.h"
-
-#include <prlock.h>
-#include <prerror.h>
+#include "pmutex.h"
 
 
 class NetAddress;
 class NetAddress;
 class ConnectionReader;
 class ConnectionReader;
@@ -69,7 +67,7 @@ PUBLISHED:
 protected:
 protected:
   void new_connection(const PT(Connection) &connection);
   void new_connection(const PT(Connection) &connection);
   virtual void connection_reset(const PT(Connection) &connection, 
   virtual void connection_reset(const PT(Connection) &connection, 
-                                PRErrorCode errcode);
+                                bool okflag);
 
 
   void add_reader(ConnectionReader *reader);
   void add_reader(ConnectionReader *reader);
   void remove_reader(ConnectionReader *reader);
   void remove_reader(ConnectionReader *reader);
@@ -82,7 +80,7 @@ protected:
   Connections _connections;
   Connections _connections;
   Readers _readers;
   Readers _readers;
   Writers _writers;
   Writers _writers;
-  PRLock *_set_mutex;
+  Mutex _set_mutex;
 
 
 private:
 private:
   friend class ConnectionReader;
   friend class ConnectionReader;

+ 127 - 316
panda/src/net/connectionReader.cxx

@@ -21,20 +21,17 @@
 #include "netDatagram.h"
 #include "netDatagram.h"
 #include "datagramTCPHeader.h"
 #include "datagramTCPHeader.h"
 #include "datagramUDPHeader.h"
 #include "datagramUDPHeader.h"
-#include "pprerror.h"
 #include "config_net.h"
 #include "config_net.h"
 #include "trueClock.h"
 #include "trueClock.h"
-
+#include "socket_udp.h"
+#include "socket_tcp.h"
+#include "mutexHolder.h"
 #include "pnotify.h"
 #include "pnotify.h"
-#include <prerror.h>
-#include <pratom.h>
-#include <algorithm>
+#include "atomicAdjust.h"
 
 
 static const int read_buffer_size = maximum_udp_datagram + datagram_udp_header_size;
 static const int read_buffer_size = maximum_udp_datagram + datagram_udp_header_size;
 
 
-// We have to impose a maximum timeout on the PR_Poll() call because
-// PR_Poll() doesn't seem to be interruptible! (!)
-static const PRUint32 max_timeout_ms = 100;
+static const int max_timeout_ms = 100;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionReader::SocketInfo::Constructor
 //     Function: ConnectionReader::SocketInfo::Constructor
@@ -56,7 +53,7 @@ SocketInfo(const PT(Connection) &connection) :
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool ConnectionReader::SocketInfo::
 bool ConnectionReader::SocketInfo::
 is_udp() const {
 is_udp() const {
-  return (PR_GetDescType(_connection->get_socket()) == PR_DESC_SOCKET_UDP);
+  return (_connection->get_socket()->is_exact_type(Socket_UDP::get_class_type()));
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -64,11 +61,34 @@ is_udp() const {
 //       Access: Public
 //       Access: Public
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-PRFileDesc *ConnectionReader::SocketInfo::
+Socket_IP *ConnectionReader::SocketInfo::
 get_socket() const {
 get_socket() const {
   return _connection->get_socket();
   return _connection->get_socket();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: ConnectionReader::ReaderThread::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+ConnectionReader::ReaderThread::
+ReaderThread(ConnectionReader *reader, int thread_index) :
+  Thread("ReaderThread", "ReaderThread"),
+  _reader(reader),
+  _thread_index(thread_index)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConnectionReader::ReaderThread::thread_main
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void ConnectionReader::ReaderThread::
+thread_main() {
+  _reader->thread_run(_thread_index);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionReader::Constructor
 //     Function: ConnectionReader::Constructor
 //       Access: Public
 //       Access: Public
@@ -83,10 +103,6 @@ ConnectionReader(ConnectionManager *manager, int num_threads) :
   _manager(manager)
   _manager(manager)
 {
 {
 #ifndef HAVE_THREADS
 #ifndef HAVE_THREADS
-  // Although this code is written to use thread-locking primitives
-  // regardless of the definition of HAVE_THREADS, it is not safe to
-  // spawn multiple threads when HAVE_THREADS is not true, since we
-  // might be using a non-thread-safe malloc scheme.
 #ifndef NDEBUG
 #ifndef NDEBUG
   if (num_threads != 0) {
   if (num_threads != 0) {
     net_cat.error()
     net_cat.error()
@@ -101,36 +117,20 @@ ConnectionReader(ConnectionManager *manager, int num_threads) :
   _polling = (num_threads <= 0);
   _polling = (num_threads <= 0);
 
 
   _shutdown = false;
   _shutdown = false;
-  _startup_mutex = PR_NewLock();
 
 
   _next_index = 0;
   _next_index = 0;
   _num_results = 0;
   _num_results = 0;
-  _select_mutex = PR_NewLock();
 
 
   _currently_polling_thread = -1;
   _currently_polling_thread = -1;
 
 
-  _reexamine_sockets = false;
-  _sockets_mutex = PR_NewLock();
-
-  // Before we create all the threads, grab _startup_mutex.  That will
-  // prevent our new threads from trying to look themselves up in the
-  // _threads array before we have filled it up.
-  PR_Lock(_startup_mutex);
-
-  for (int i = 0; i < num_threads; i++) {
-    PRThread *thread =
-      PR_CreateThread(PR_USER_THREAD,
-                      thread_start, (void *)this,
-                      PR_PRIORITY_NORMAL,
-                      PR_GLOBAL_THREAD, // Since thread will mostly do I/O.
-                      PR_JOINABLE_THREAD,
-                      0);  // Select a suitable stack size.
-
-    nassertv(thread != (PRThread *)NULL);
+  int i;
+  for (i = 0; i < num_threads; i++) {
+    PT(ReaderThread) thread = new ReaderThread(this, i);
     _threads.push_back(thread);
     _threads.push_back(thread);
   }
   }
-
-  PR_Unlock(_startup_mutex);
+  for (i = 0; i < num_threads; i++) {
+    _threads[i]->start(TP_normal, true, true);
+  }
 
 
   _manager->add_reader(this);
   _manager->add_reader(this);
 }
 }
@@ -166,10 +166,6 @@ ConnectionReader::
       sinfo->_connection.clear();
       sinfo->_connection.clear();
     }
     }
   }
   }
-
-  PR_DestroyLock(_startup_mutex);
-  PR_DestroyLock(_select_mutex);
-  PR_DestroyLock(_sockets_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -190,24 +186,21 @@ ConnectionReader::
 //               will by any thread.
 //               will by any thread.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool ConnectionReader::
 bool ConnectionReader::
-add_connection(const PT(Connection) &connection) {
+add_connection(Connection *connection) {
   nassertr(connection != (Connection *)NULL, false);
   nassertr(connection != (Connection *)NULL, false);
 
 
-  PR_Lock(_sockets_mutex);
+  MutexHolder holder(_sockets_mutex);
 
 
   // Make sure it's not already on the _sockets list.
   // Make sure it's not already on the _sockets list.
   Sockets::const_iterator si;
   Sockets::const_iterator si;
   for (si = _sockets.begin(); si != _sockets.end(); ++si) {
   for (si = _sockets.begin(); si != _sockets.end(); ++si) {
     if ((*si)->_connection == connection) {
     if ((*si)->_connection == connection) {
       // Whoops, already there.
       // Whoops, already there.
-      PR_Unlock(_sockets_mutex);
       return false;
       return false;
     }
     }
   }
   }
 
 
   _sockets.push_back(new SocketInfo(connection));
   _sockets.push_back(new SocketInfo(connection));
-  _reexamine_sockets = true;
-  PR_Unlock(_sockets_mutex);
 
 
   return true;
   return true;
 }
 }
@@ -224,8 +217,8 @@ add_connection(const PT(Connection) &connection) {
 //               at will by any thread.
 //               at will by any thread.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool ConnectionReader::
 bool ConnectionReader::
-remove_connection(const PT(Connection) &connection) {
-  PR_Lock(_sockets_mutex);
+remove_connection(Connection *connection) {
+  MutexHolder holder(_sockets_mutex);
 
 
   // Walk through the list of sockets to find the one we're removing.
   // Walk through the list of sockets to find the one we're removing.
   Sockets::iterator si;
   Sockets::iterator si;
@@ -234,14 +227,11 @@ remove_connection(const PT(Connection) &connection) {
     ++si;
     ++si;
   }
   }
   if (si == _sockets.end()) {
   if (si == _sockets.end()) {
-    PR_Unlock(_sockets_mutex);
     return false;
     return false;
   }
   }
 
 
   _removed_sockets.push_back(*si);
   _removed_sockets.push_back(*si);
   _sockets.erase(si);
   _sockets.erase(si);
-  _reexamine_sockets = true;
-  PR_Unlock(_sockets_mutex);
 
 
   return true;
   return true;
 }
 }
@@ -258,8 +248,8 @@ remove_connection(const PT(Connection) &connection) {
 //               the connection.)
 //               the connection.)
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool ConnectionReader::
 bool ConnectionReader::
-is_connection_ok(const PT(Connection) &connection) {
-  PR_Lock(_sockets_mutex);
+is_connection_ok(Connection *connection) {
+  MutexHolder holder(_sockets_mutex);
 
 
   // Walk through the list of sockets to find the one we're asking
   // Walk through the list of sockets to find the one we're asking
   // about.
   // about.
@@ -270,13 +260,11 @@ is_connection_ok(const PT(Connection) &connection) {
   }
   }
   if (si == _sockets.end()) {
   if (si == _sockets.end()) {
     // Don't know that connection.
     // Don't know that connection.
-    PR_Unlock(_sockets_mutex);
     return false;
     return false;
   }
   }
 
 
   SocketInfo *sinfo = (*si);
   SocketInfo *sinfo = (*si);
   bool is_ok = !sinfo->_error;
   bool is_ok = !sinfo->_error;
-  PR_Unlock(_sockets_mutex);
 
 
   return is_ok;
   return is_ok;
 }
 }
@@ -299,14 +287,14 @@ poll() {
     return;
     return;
   }
   }
 
 
-  SocketInfo *sinfo = get_next_available_socket(PR_INTERVAL_NO_WAIT, -2);
+  SocketInfo *sinfo = get_next_available_socket(false, -2);
   if (sinfo != (SocketInfo *)NULL) {
   if (sinfo != (SocketInfo *)NULL) {
     double max_poll_cycle = get_max_poll_cycle();
     double max_poll_cycle = get_max_poll_cycle();
     if (max_poll_cycle < 0.0) {
     if (max_poll_cycle < 0.0) {
       // Continue to read all data.
       // Continue to read all data.
       while (sinfo != (SocketInfo *)NULL) {
       while (sinfo != (SocketInfo *)NULL) {
 	process_incoming_data(sinfo);
 	process_incoming_data(sinfo);
-	sinfo = get_next_available_socket(PR_INTERVAL_NO_WAIT, -2);
+	sinfo = get_next_available_socket(false, -2);
       }
       }
 
 
     } else {
     } else {
@@ -319,7 +307,7 @@ poll() {
 	if (global_clock->get_short_time() >= stop) {
 	if (global_clock->get_short_time() >= stop) {
 	  return;
 	  return;
 	}
 	}
-	sinfo = get_next_available_socket(PR_INTERVAL_NO_WAIT, -2);
+	sinfo = get_next_available_socket(false, -2);
       }
       }
     }
     }
   }
   }
@@ -429,16 +417,7 @@ shutdown() {
   // Now wait for all of our threads to terminate.
   // Now wait for all of our threads to terminate.
   Threads::iterator ti;
   Threads::iterator ti;
   for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
   for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
-    // Interrupt the thread so it can notice the shutdown.
-    PRStatus result = PR_Interrupt(*ti);
-    if (result != PR_SUCCESS) {
-      pprerror("PR_Interrupt");
-    }
-
-    result = PR_JoinThread(*ti);
-    if (result != PR_SUCCESS) {
-      pprerror("PR_JoinThread");
-    }
+    (*ti)->join();
   }
   }
 }
 }
 
 
@@ -470,34 +449,14 @@ finish_socket(SocketInfo *sinfo) {
   // By marking the SocketInfo nonbusy, we make it available for
   // By marking the SocketInfo nonbusy, we make it available for
   // future polls.
   // future polls.
   sinfo->_busy = false;
   sinfo->_busy = false;
-  _reexamine_sockets = true;
-
-  // However, someone might be already blocking on an
-  // earlier-established PR_Poll() that doesn't involve this socket.
-  // That complicates things.  It means we'll have to wake that thread
-  // up so it can rebuild the poll with the new socket.
-
-  // Actually, don't bother, since it turns out that PR_Poll() isn't
-  // interruptible anyway.  Sigh.  Maybe we'll revisit this later, but
-  // in the meantime it means we have to rig up the PR_Poll() to
-  // return every so often and check the _reexamine_sockets flag by
-  // itself.
-
-  /*
-  int thread = _currently_polling_thread;
-  if (thread != -1) {
-    nassertv(thread >= 0 && thread < _threads.size());
-    PR_Interrupt(_threads[thread]);
-  }
-  */
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionReader::process_incoming_data
 //     Function: ConnectionReader::process_incoming_data
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
 //  Description: This is run within a thread when the call to
 //  Description: This is run within a thread when the call to
-//               PR_Poll() indicates there is data available
-//               on a socket.
+//               select() indicates there is data available on a
+//               socket.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
 process_incoming_data(SocketInfo *sinfo) {
 process_incoming_data(SocketInfo *sinfo) {
@@ -523,21 +482,17 @@ process_incoming_data(SocketInfo *sinfo) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
 process_incoming_udp_data(SocketInfo *sinfo) {
 process_incoming_udp_data(SocketInfo *sinfo) {
-  PRFileDesc *socket = sinfo->get_socket();
-  PRNetAddr addr;
+  Socket_UDP *socket;
+  DCAST_INTO_V(socket, sinfo->get_socket());
+  Socket_Address addr;
 
 
   // Read as many bytes as we can.
   // Read as many bytes as we can.
-  PRInt8 buffer[read_buffer_size];
-  PRInt32 bytes_read;
+  char buffer[read_buffer_size];
+  int bytes_read = read_buffer_size;
 
 
-  bytes_read = PR_RecvFrom(socket, buffer, read_buffer_size, 0,
-                           &addr, PR_INTERVAL_NO_TIMEOUT);
+  bool okflag = socket->GetPacket(buffer, &bytes_read, addr);
 
 
-  if (bytes_read < 0) {
-    PRErrorCode errcode = PR_GetError();
-    if (errcode != PR_PENDING_INTERRUPT_ERROR) {
-      pprerror("PR_RecvFrom");
-    }
+  if (!okflag) {
     finish_socket(sinfo);
     finish_socket(sinfo);
     return;
     return;
 
 
@@ -563,7 +518,7 @@ process_incoming_udp_data(SocketInfo *sinfo) {
   
   
   DatagramUDPHeader header(buffer);
   DatagramUDPHeader header(buffer);
   
   
-  PRInt8 *dp = buffer + datagram_udp_header_size;
+  char *dp = buffer + datagram_udp_header_size;
   bytes_read -= datagram_udp_header_size;
   bytes_read -= datagram_udp_header_size;
   
   
   NetDatagram datagram(dp, bytes_read);
   NetDatagram datagram(dp, bytes_read);
@@ -594,44 +549,20 @@ process_incoming_udp_data(SocketInfo *sinfo) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
 process_incoming_tcp_data(SocketInfo *sinfo) {
 process_incoming_tcp_data(SocketInfo *sinfo) {
-  PRFileDesc *socket = sinfo->get_socket();
-  PRNetAddr addr;
+  Socket_TCP *socket;
+  DCAST_INTO_V(socket, sinfo->get_socket());
 
 
   // Read only the header bytes to start with.
   // Read only the header bytes to start with.
-  PRInt8 buffer[read_buffer_size];
-  PRInt32 header_bytes_read = 0;
-
-  if (PR_GetSockName(socket, &addr) != PR_SUCCESS) {
-    pprerror("PR_GetSockName");
-  }
+  char buffer[read_buffer_size];
+  int header_bytes_read = 0;
 
 
   // First, we have to read the first _tcp_header_size bytes.
   // First, we have to read the first _tcp_header_size bytes.
   while (header_bytes_read < _tcp_header_size) {
   while (header_bytes_read < _tcp_header_size) {
-    PRInt32 bytes_read =
-      PR_Recv(socket, buffer + header_bytes_read,
-              _tcp_header_size - header_bytes_read, 0,
-              PR_INTERVAL_NO_TIMEOUT);
-
-    if (bytes_read < 0) {
-      PRErrorCode errcode = PR_GetError();
-      if (errcode == PR_CONNECT_RESET_ERROR
-#ifdef PR_SOCKET_SHUTDOWN_ERROR
-          || errcode == PR_SOCKET_SHUTDOWN_ERROR
-          || errcode == PR_CONNECT_ABORTED_ERROR
-#endif
-          ) {
-        // The socket was closed.
-        if (_manager != (ConnectionManager *)NULL) {
-          _manager->connection_reset(sinfo->_connection, errcode);
-        }
-
-      } else if (errcode != PR_PENDING_INTERRUPT_ERROR) {
-        pprerror("PR_Recv");
-      }
-      finish_socket(sinfo);
-      return;
+    int bytes_read =
+      socket->RecvData(buffer + header_bytes_read,
+                       _tcp_header_size - header_bytes_read);
 
 
-    } else if (bytes_read == 0) {
+    if (bytes_read <= 0) {
       // The socket was closed.  Report that and return.
       // The socket was closed.  Report that and return.
       if (_manager != (ConnectionManager *)NULL) {
       if (_manager != (ConnectionManager *)NULL) {
         _manager->connection_reset(sinfo->_connection, 0);
         _manager->connection_reset(sinfo->_connection, 0);
@@ -655,41 +586,20 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
   }
   }
 
 
   DatagramTCPHeader header(buffer, _tcp_header_size);
   DatagramTCPHeader header(buffer, _tcp_header_size);
-  PRInt32 size = header.get_datagram_size(_tcp_header_size);
+  int size = header.get_datagram_size(_tcp_header_size);
 
 
   // We have to loop until the entire datagram is read.
   // We have to loop until the entire datagram is read.
   NetDatagram datagram;
   NetDatagram datagram;
 
 
   while (!_shutdown && (int)datagram.get_length() < size) {
   while (!_shutdown && (int)datagram.get_length() < size) {
-    PRInt32 bytes_read;
+    int bytes_read;
 
 
     bytes_read =
     bytes_read =
-      PR_Recv(socket, buffer,
-              min((PRInt32)read_buffer_size,
-                  (PRInt32)(size - datagram.get_length())),
-              0, PR_INTERVAL_NO_TIMEOUT);
-    PRInt8 *dp = buffer;
-
-    if (bytes_read < 0) {
-      PRErrorCode errcode = PR_GetError();
-      if (errcode == PR_CONNECT_RESET_ERROR
-#ifdef PR_SOCKET_SHUTDOWN_ERROR
-          || errcode == PR_SOCKET_SHUTDOWN_ERROR
-          || errcode == PR_CONNECT_ABORTED_ERROR
-#endif
-          ) {
-        // The socket was closed.
-        if (_manager != (ConnectionManager *)NULL) {
-          _manager->connection_reset(sinfo->_connection, errcode);
-        }
+      socket->RecvData(buffer, min(read_buffer_size,
+                                   (int)(size - datagram.get_length())));
+    char *dp = buffer;
 
 
-      } else if (errcode != PR_PENDING_INTERRUPT_ERROR) {
-        pprerror("PR_Recv");
-      }
-      finish_socket(sinfo);
-      return;
-
-    } else if (bytes_read == 0) {
+    if (bytes_read <= 0) {
       // The socket was closed.  Report that and return.
       // The socket was closed.  Report that and return.
       if (_manager != (ConnectionManager *)NULL) {
       if (_manager != (ConnectionManager *)NULL) {
         _manager->connection_reset(sinfo->_connection, 0);
         _manager->connection_reset(sinfo->_connection, 0);
@@ -698,8 +608,8 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
       return;
       return;
     }
     }
 
 
-    PRInt32 datagram_bytes =
-      min(bytes_read, (PRInt32)(size - datagram.get_length()));
+    int datagram_bytes =
+      min(bytes_read, (int)(size - datagram.get_length()));
     datagram.append_data(dp, datagram_bytes);
     datagram.append_data(dp, datagram_bytes);
 
 
     if (bytes_read > datagram_bytes) {
     if (bytes_read > datagram_bytes) {
@@ -725,7 +635,7 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
       << "Ignoring invalid TCP datagram.\n";
       << "Ignoring invalid TCP datagram.\n";
   } else {
   } else {
     datagram.set_connection(sinfo->_connection);
     datagram.set_connection(sinfo->_connection);
-    datagram.set_address(NetAddress(addr));
+    datagram.set_address(NetAddress(socket->GetPeerName()));
     receive_datagram(datagram);
     receive_datagram(datagram);
   }
   }
 }
 }
@@ -737,21 +647,17 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
 process_raw_incoming_udp_data(SocketInfo *sinfo) {
 process_raw_incoming_udp_data(SocketInfo *sinfo) {
-  PRFileDesc *socket = sinfo->get_socket();
-  PRNetAddr addr;
+  Socket_UDP *socket;
+  DCAST_INTO_V(socket, sinfo->get_socket());
+  Socket_Address addr;
 
 
   // Read as many bytes as we can.
   // Read as many bytes as we can.
-  PRInt8 buffer[read_buffer_size];
-  PRInt32 bytes_read;
+  char buffer[read_buffer_size];
+  int bytes_read = read_buffer_size;
 
 
-  bytes_read = PR_RecvFrom(socket, buffer, read_buffer_size, 0,
-                           &addr, PR_INTERVAL_NO_TIMEOUT);
+  bool okflag = socket->GetPacket(buffer, &bytes_read, addr);
 
 
-  if (bytes_read < 0) {
-    PRErrorCode errcode = PR_GetError();
-    if (errcode != PR_PENDING_INTERRUPT_ERROR) {
-      pprerror("PR_RecvFrom");
-    }
+  if (!okflag) {
     finish_socket(sinfo);
     finish_socket(sinfo);
     return;
     return;
 
 
@@ -789,29 +695,14 @@ process_raw_incoming_udp_data(SocketInfo *sinfo) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
 process_raw_incoming_tcp_data(SocketInfo *sinfo) {
 process_raw_incoming_tcp_data(SocketInfo *sinfo) {
-  PRFileDesc *socket = sinfo->get_socket();
-  PRNetAddr addr;
+  Socket_TCP *socket;
+  DCAST_INTO_V(socket, sinfo->get_socket());
 
 
   // Read as many bytes as we can.
   // Read as many bytes as we can.
-  PRInt8 buffer[read_buffer_size];
-  PRInt32 bytes_read;
-
-  if (PR_GetSockName(socket, &addr) != PR_SUCCESS) {
-    pprerror("PR_GetSockName");
-  }
+  char buffer[read_buffer_size];
+  int bytes_read = socket->RecvData(buffer, read_buffer_size);
 
 
-  bytes_read = PR_Recv(socket, buffer, read_buffer_size, 0,
-                       PR_INTERVAL_NO_TIMEOUT);
-
-  if (bytes_read < 0) {
-    PRErrorCode errcode = PR_GetError();
-    if (errcode != PR_PENDING_INTERRUPT_ERROR) {
-      pprerror("PR_RecvFrom");
-    }
-    finish_socket(sinfo);
-    return;
-
-  } else if (bytes_read == 0) {
+  if (bytes_read <= 0) {
     // The socket was closed.  Report that and return.
     // The socket was closed.  Report that and return.
     if (_manager != (ConnectionManager *)NULL) {
     if (_manager != (ConnectionManager *)NULL) {
       _manager->connection_reset(sinfo->_connection, 0);
       _manager->connection_reset(sinfo->_connection, 0);
@@ -833,24 +724,10 @@ process_raw_incoming_tcp_data(SocketInfo *sinfo) {
   }
   }
   
   
   datagram.set_connection(sinfo->_connection);
   datagram.set_connection(sinfo->_connection);
-  datagram.set_address(NetAddress(addr));
+  datagram.set_address(NetAddress(socket->GetPeerName()));
   receive_datagram(datagram);
   receive_datagram(datagram);
 }
 }
 
 
-
-////////////////////////////////////////////////////////////////////
-//     Function: ConnectionReader::thread_start
-//       Access: Private, Static
-//  Description: The static wrapper around the thread's executing
-//               function.  This must be a static member function
-//               because it is passed through the C interface to
-//               PR_CreateThread().
-////////////////////////////////////////////////////////////////////
-void ConnectionReader::
-thread_start(void *data) {
-  ((ConnectionReader *)data)->thread_run();
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionReader::thread_run
 //     Function: ConnectionReader::thread_run
 //       Access: Private
 //       Access: Private
@@ -858,24 +735,13 @@ thread_start(void *data) {
 //               thread.
 //               thread.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
-thread_run() {
+thread_run(int thread_index) {
   nassertv(!_polling);
   nassertv(!_polling);
-
-  // First determine our own thread index.
-  PR_Lock(_startup_mutex);
-  Threads::const_iterator ti =
-    find(_threads.begin(), _threads.end(), PR_GetCurrentThread());
-
-  nassertv(ti != _threads.end());
-  PRInt32 current_thread_index = (ti - _threads.begin());
-
-  nassertv(_threads[current_thread_index] == PR_GetCurrentThread());
-  PR_Unlock(_startup_mutex);
+  nassertv(_threads[thread_index] == Thread::get_current_thread());
 
 
   while (!_shutdown) {
   while (!_shutdown) {
     SocketInfo *sinfo =
     SocketInfo *sinfo =
-      get_next_available_socket(PR_INTERVAL_NO_TIMEOUT,
-                                current_thread_index);
+      get_next_available_socket(false, thread_index);
     if (sinfo != (SocketInfo *)NULL) {
     if (sinfo != (SocketInfo *)NULL) {
       process_incoming_data(sinfo);
       process_incoming_data(sinfo);
     }
     }
@@ -892,59 +758,29 @@ thread_run() {
 //
 //
 //               This function may block indefinitely if it is being
 //               This function may block indefinitely if it is being
 //               called by multiple threads; if there are no other
 //               called by multiple threads; if there are no other
-//               threads, it may block only if timeout !=
-//               PR_INTERVAL_NO_WAIT.
+//               threads, it may block only if allow_block is true.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 ConnectionReader::SocketInfo *ConnectionReader::
 ConnectionReader::SocketInfo *ConnectionReader::
-get_next_available_socket(PRIntervalTime timeout,
-                          PRInt32 current_thread_index) {
+get_next_available_socket(bool allow_block, int current_thread_index) {
   // Go to sleep on the select() mutex.  This guarantees that only one
   // Go to sleep on the select() mutex.  This guarantees that only one
   // thread is in this function at a time.
   // thread is in this function at a time.
-  PR_Lock(_select_mutex);
-
-  int num_sockets = _polled_sockets.size();
-  nassertr(num_sockets == (int)_poll.size(), NULL);
+  MutexHolder holder(_select_mutex);
 
 
   do {
   do {
-    // First, check the result from the previous PR_Poll() call.  If
+    // First, check the result from the previous select call.  If
     // there are any sockets remaining there, process them first.
     // there are any sockets remaining there, process them first.
     while (!_shutdown && _num_results > 0) {
     while (!_shutdown && _num_results > 0) {
-      nassertr(_next_index < num_sockets, NULL);
+      nassertr(_next_index < (int)_selecting_sockets.size(), NULL);
       int i = _next_index;
       int i = _next_index;
       _next_index++;
       _next_index++;
 
 
-      if (_poll[i].out_flags != 0) {
+      if (_fdset.IsSetFor(*_selecting_sockets[i]->get_socket())) {
         _num_results--;
         _num_results--;
-        SocketInfo *sinfo = _polled_sockets[i];
-
-        if ((_poll[i].out_flags & PR_POLL_READ) != 0) {
-          // Some genuine noise on the port.
-          sinfo->_busy = true;
-          _reexamine_sockets = true;
-          PR_Unlock(_select_mutex);
-          PR_Sleep(PR_INTERVAL_NO_WAIT);
-          return sinfo;
-
-        } else if ((_poll[i].out_flags &
-                    (PR_POLL_ERR | PR_POLL_NVAL | PR_POLL_HUP)) != 0) {
-          // Something bad happened to this socket.  Tell the
-          // ConnectionManager to drop it.
-          if (_manager != (ConnectionManager *)NULL) {
-            // Perform a recv to force an error code.
-            char buffer[1];
-            PRInt32 got_bytes =
-              PR_Recv(sinfo->get_socket(), buffer, 1, 0, PR_INTERVAL_NO_WAIT);
-            if (got_bytes > 0) {
-              net_cat.error()
-                << "poll returned error flags " << hex << _poll[i].out_flags
-                << dec << " but read " << got_bytes << " from socket.\n";
-            }
-            PRErrorCode errcode = PR_GetError();
-            _manager->connection_reset(sinfo->_connection, errcode);
-          }
-          sinfo->_error = true;
-          _reexamine_sockets = true;
-        }
+        SocketInfo *sinfo = _selecting_sockets[i];
+
+        // Some noise on this socket.
+        sinfo->_busy = true;
+        return sinfo;
       }
       }
     }
     }
 
 
@@ -952,93 +788,70 @@ get_next_available_socket(PRIntervalTime timeout,
     do {
     do {
       interrupted = false;
       interrupted = false;
 
 
-      // Ok, no results from previous PR_Poll() calls.  Prepare to set
-      // up for a new poll.
+      // Ok, no results from previous select calls.  Prepare to set up
+      // for a new select.
 
 
       // First, report to anyone else who cares that we're the thread
       // First, report to anyone else who cares that we're the thread
       // about to do the poll.  That way, if any new sockets come
       // about to do the poll.  That way, if any new sockets come
       // available while we're polling, we can service them.
       // available while we're polling, we can service them.
-      PR_AtomicSet(&_currently_polling_thread, current_thread_index);
-
-      if (_reexamine_sockets) {
-        _reexamine_sockets = false;
-        rebuild_poll_list();
-        num_sockets = _polled_sockets.size();
-        nassertr(num_sockets == (int)_poll.size(), NULL);
-      }
+      AtomicAdjust::set(_currently_polling_thread, current_thread_index);
+      
+      rebuild_select_list();
 
 
-      // Now we can execute PR_Poll().  This basically maps to a Unix
-      // select() call.
+      // Now we can execute the select.
       _num_results = 0;
       _num_results = 0;
       _next_index = 0;
       _next_index = 0;
 
 
       if (!_shutdown) {
       if (!_shutdown) {
-        PRIntervalTime poll_timeout =
-          PR_MillisecondsToInterval(max_timeout_ms);
-        if (timeout != PR_INTERVAL_NO_TIMEOUT) {
-          poll_timeout = min(timeout, poll_timeout);
+        PN_uint32 timeout = max_timeout_ms;
+        if (!allow_block) {
+          timeout = 0;
         }
         }
 
 
-        _num_results = PR_Poll(&_poll[0], num_sockets, poll_timeout);
+        _num_results = _fdset.WaitForRead(false, timeout);
       }
       }
 
 
-      if (_num_results == 0 && timeout == PR_INTERVAL_NO_TIMEOUT) {
-        // If we reached max_timeout_ms, but the caller didn't request
-        // a timeout, consider that an interrupt: go back and
-        // reconsider.  (This is a kludge around the fact that
-        // PR_Poll() appears to be non-interruptible.)
+      if (_num_results == 0 && allow_block) {
+        // If we reached max_timeout_ms, go back and reconsider.  (We
+        // never timeout indefinitely, so we can check the shutdown
+        // flag every once in a while.)
         interrupted = true;
         interrupted = true;
 
 
       } else if (_num_results < 0) {
       } else if (_num_results < 0) {
-        // If our poll was interrupted by another thread, rebuild the
-        // list and poll again.
-        PRErrorCode errcode = PR_GetError();
-        if (errcode == PR_PENDING_INTERRUPT_ERROR) {
-          interrupted = true;
-        } else {
-          pprerror("PR_Poll");
-        }
+        // If we had an error, just return.
+        return (SocketInfo *)NULL;
       }
       }
     } while (!_shutdown && interrupted);
     } while (!_shutdown && interrupted);
 
 
-    PR_AtomicSet(&_currently_polling_thread, -1);
-    // Just in case someone interrupted us while we were polling and
-    // we didn't catch it, clear it now--we don't care any more.
-    PR_ClearInterrupt();
+    AtomicAdjust::set(_currently_polling_thread, current_thread_index);
 
 
     // Repeat the above until we (a) find a socket with actual noise
     // Repeat the above until we (a) find a socket with actual noise
     // on it, or (b) return from PR_Poll() with no sockets available.
     // on it, or (b) return from PR_Poll() with no sockets available.
   } while (!_shutdown && _num_results > 0);
   } while (!_shutdown && _num_results > 0);
 
 
-  PR_Unlock(_select_mutex);
   return (SocketInfo *)NULL;
   return (SocketInfo *)NULL;
 }
 }
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: ConnectionReader::rebuild_poll_list
+//     Function: ConnectionReader::rebuild_select_list
 //       Access: Private
 //       Access: Private
-//  Description: Rebuilds the _poll and _polled_sockets arrays based
-//               on the sockets that are currently available for
-//               polling.
+//  Description: Rebuilds the _fdset and _selecting_sockets arrays
+//               based on the sockets that are currently available for
+//               selecting.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionReader::
 void ConnectionReader::
-rebuild_poll_list() {
-  _poll.clear();
-  _polled_sockets.clear();
+rebuild_select_list() {
+  _fdset.clear();
+  _selecting_sockets.clear();
 
 
-  PR_Lock(_sockets_mutex);
+  MutexHolder holder(_sockets_mutex);
   Sockets::const_iterator si;
   Sockets::const_iterator si;
   for (si = _sockets.begin(); si != _sockets.end(); ++si) {
   for (si = _sockets.begin(); si != _sockets.end(); ++si) {
     SocketInfo *sinfo = (*si);
     SocketInfo *sinfo = (*si);
     if (!sinfo->_busy && !sinfo->_error) {
     if (!sinfo->_busy && !sinfo->_error) {
-      PRPollDesc pd;
-      pd.fd = sinfo->get_socket();
-      pd.in_flags = PR_POLL_READ;
-      pd.out_flags = 0;
-
-      _poll.push_back(pd);
-      _polled_sockets.push_back(sinfo);
+      _fdset.setForSocket(*sinfo->get_socket());
+      _selecting_sockets.push_back(sinfo);
     }
     }
   }
   }
 
 
@@ -1056,6 +869,4 @@ rebuild_poll_list() {
     }
     }
     _removed_sockets.swap(still_busy_sockets);
     _removed_sockets.swap(still_busy_sockets);
   }
   }
-
-  PR_Unlock(_sockets_mutex);
 }
 }

+ 30 - 26
panda/src/net/connectionReader.h

@@ -24,15 +24,15 @@
 #include "connection.h"
 #include "connection.h"
 
 
 #include "pointerTo.h"
 #include "pointerTo.h"
-
-#include <prio.h>
-#include <prthread.h>
-#include <prlock.h>
+#include "pmutex.h"
 #include "pvector.h"
 #include "pvector.h"
 #include "pset.h"
 #include "pset.h"
+#include "socket_fdset.h"
 
 
 class NetDatagram;
 class NetDatagram;
 class ConnectionManager;
 class ConnectionManager;
+class Socket_Address;
+class Socket_IP;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : ConnectionReader
 //       Class : ConnectionReader
@@ -72,9 +72,9 @@ PUBLISHED:
   ConnectionReader(ConnectionManager *manager, int num_threads);
   ConnectionReader(ConnectionManager *manager, int num_threads);
   virtual ~ConnectionReader();
   virtual ~ConnectionReader();
 
 
-  bool add_connection(const PT(Connection) &connection);
-  bool remove_connection(const PT(Connection) &connection);
-  bool is_connection_ok(const PT(Connection) &connection);
+  bool add_connection(Connection *connection);
+  bool remove_connection(Connection *connection);
+  bool is_connection_ok(Connection *connection);
 
 
   void poll();
   void poll();
 
 
@@ -95,7 +95,7 @@ protected:
   public:
   public:
     SocketInfo(const PT(Connection) &connection);
     SocketInfo(const PT(Connection) &connection);
     bool is_udp() const;
     bool is_udp() const;
-    PRFileDesc *get_socket() const;
+    Socket_IP *get_socket() const;
 
 
     PT(Connection) _connection;
     PT(Connection) _connection;
     bool _busy;
     bool _busy;
@@ -113,13 +113,12 @@ protected:
   virtual void process_raw_incoming_tcp_data(SocketInfo *sinfo);
   virtual void process_raw_incoming_tcp_data(SocketInfo *sinfo);
 
 
 private:
 private:
-  static void thread_start(void *data);
-  void thread_run();
+  void thread_run(int thread_index);
 
 
-  SocketInfo *get_next_available_socket(PRIntervalTime timeout,
-                                        PRInt32 current_thread_index);
+  SocketInfo *get_next_available_socket(bool allow_block, 
+                                        int current_thread_index);
 
 
-  void rebuild_poll_list();
+  void rebuild_select_list();
 
 
 protected:
 protected:
   ConnectionManager *_manager;
   ConnectionManager *_manager;
@@ -129,27 +128,34 @@ private:
   int _tcp_header_size;
   int _tcp_header_size;
   bool _shutdown;
   bool _shutdown;
 
 
-  typedef pvector<PRThread *> Threads;
+  class ReaderThread : public Thread {
+  public:
+    ReaderThread(ConnectionReader *reader, int thread_index);
+    virtual void thread_main();
+
+    ConnectionReader *_reader;
+    int _thread_index;
+  };
+
+  typedef pvector< PT(ReaderThread) > Threads;
   Threads _threads;
   Threads _threads;
-  PRLock *_startup_mutex;
   bool _polling;
   bool _polling;
 
 
-  // These structures are used to manage polling for noise on
+  // These structures are used to manage selecting for noise on
   // available sockets.
   // available sockets.
-  typedef pvector<PRPollDesc> Poll;
+  Socket_fdset _fdset;
   typedef pvector<SocketInfo *> Sockets;
   typedef pvector<SocketInfo *> Sockets;
-  Poll _poll;
-  Sockets _polled_sockets;
+  Sockets _selecting_sockets;
   int _next_index;
   int _next_index;
   int _num_results;
   int _num_results;
   // Threads go to sleep on this mutex waiting for their chance to
   // Threads go to sleep on this mutex waiting for their chance to
   // read a socket.
   // read a socket.
-  PRLock *_select_mutex;
+  Mutex _select_mutex;
 
 
   // This is atomically updated with the index (in _threads) of the
   // This is atomically updated with the index (in _threads) of the
   // thread that is currently waiting on the PR_Poll() call.  It
   // thread that is currently waiting on the PR_Poll() call.  It
   // contains -1 if no thread is so waiting.
   // contains -1 if no thread is so waiting.
-  PRInt32 _currently_polling_thread;
+  PN_int32 _currently_polling_thread;
 
 
   // These structures track the total set of sockets (connections) we
   // These structures track the total set of sockets (connections) we
   // know about.
   // know about.
@@ -157,14 +163,12 @@ private:
   // This is the list of recently-removed sockets.  We can't actually
   // This is the list of recently-removed sockets.  We can't actually
   // delete them until they're no longer _busy.
   // delete them until they're no longer _busy.
   Sockets _removed_sockets;
   Sockets _removed_sockets;
-  // Threads may set this true to force the polling thread to rebuild
-  // its Poll() list.
-  bool _reexamine_sockets;
   // Any operations on _sockets are protected by this mutex.
   // Any operations on _sockets are protected by this mutex.
-  PRLock *_sockets_mutex;
+  Mutex _sockets_mutex;
 
 
 
 
-friend class ConnectionManager;
+  friend class ConnectionManager;
+  friend class ReaderThread;
 };
 };
 
 
 #endif
 #endif

+ 36 - 41
panda/src/net/connectionWriter.cxx

@@ -19,11 +19,33 @@
 #include "connectionWriter.h"
 #include "connectionWriter.h"
 #include "connectionManager.h"
 #include "connectionManager.h"
 #include "datagramTCPHeader.h"
 #include "datagramTCPHeader.h"
-#include "pprerror.h"
 #include "config_net.h"
 #include "config_net.h"
-
+#include "socket_tcp.h"
+#include "socket_udp.h"
 #include "pnotify.h"
 #include "pnotify.h"
-#include <prerror.h>
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConnectionWriter::WriterThread::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+ConnectionWriter::WriterThread::
+WriterThread(ConnectionWriter *writer, int thread_index) :
+  Thread("WriterThread", "WriterThread"),
+  _writer(writer),
+  _thread_index(thread_index)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ConnectionWriter::WriterThread::thread_main
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void ConnectionWriter::WriterThread::
+thread_main() {
+  _writer->thread_run(_thread_index);
+}
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionWriter::Constructor
 //     Function: ConnectionWriter::Constructor
@@ -57,18 +79,14 @@ ConnectionWriter(ConnectionManager *manager, int num_threads) :
   _tcp_header_size = datagram_tcp16_header_size;
   _tcp_header_size = datagram_tcp16_header_size;
   _immediate = (num_threads <= 0);
   _immediate = (num_threads <= 0);
 
 
-  for (int i = 0; i < num_threads; i++) {
-    PRThread *thread =
-      PR_CreateThread(PR_USER_THREAD,
-                      thread_start, (void *)this,
-                      PR_PRIORITY_NORMAL,
-                      PR_GLOBAL_THREAD, // Since thread will mostly do I/O.
-                      PR_JOINABLE_THREAD,
-                      0);  // Select a suitable stack size.
-
-    nassertv(thread != (PRThread *)NULL);
+  int i;
+  for (i = 0; i < num_threads; i++) {
+    PT(WriterThread) thread = new WriterThread(this, i);
     _threads.push_back(thread);
     _threads.push_back(thread);
   }
   }
+  for (i = 0; i < num_threads; i++) {
+    _threads[i]->start(TP_normal, true, true);
+  }
 
 
   _manager->add_writer(this);
   _manager->add_writer(this);
 }
 }
@@ -91,16 +109,7 @@ ConnectionWriter::
   // Now wait for all threads to terminate.
   // Now wait for all threads to terminate.
   Threads::iterator ti;
   Threads::iterator ti;
   for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
   for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
-    // Interrupt the thread just in case it was stuck waiting for I/O.
-    PRStatus result = PR_Interrupt(*ti);
-    if (result != PR_SUCCESS) {
-      pprerror("PR_Interrupt");
-    }
-
-    result = PR_JoinThread(*ti);
-    if (result != PR_SUCCESS) {
-      pprerror("PR_JoinThread");
-    }
+    (*ti)->join();
   }
   }
 }
 }
 
 
@@ -123,7 +132,7 @@ ConnectionWriter::
 bool ConnectionWriter::
 bool ConnectionWriter::
 send(const Datagram &datagram, const PT(Connection) &connection) {
 send(const Datagram &datagram, const PT(Connection) &connection) {
   nassertr(connection != (Connection *)NULL, false);
   nassertr(connection != (Connection *)NULL, false);
-  nassertr(PR_GetDescType(connection->get_socket()) == PR_DESC_SOCKET_TCP, false);
+  nassertr(connection->get_socket()->is_exact_type(Socket_TCP::get_class_type()), false);
 
 
   NetDatagram copy(datagram);
   NetDatagram copy(datagram);
   copy.set_connection(connection);
   copy.set_connection(connection);
@@ -159,10 +168,9 @@ bool ConnectionWriter::
 send(const Datagram &datagram, const PT(Connection) &connection,
 send(const Datagram &datagram, const PT(Connection) &connection,
      const NetAddress &address) {
      const NetAddress &address) {
   nassertr(connection != (Connection *)NULL, false);
   nassertr(connection != (Connection *)NULL, false);
-  nassertr(PR_GetDescType(connection->get_socket()) == PR_DESC_SOCKET_UDP, false);
+  nassertr(connection->get_socket()->is_exact_type(Socket_UDP::get_class_type()), false);
 
 
-  if (PR_GetDescType(connection->get_socket()) == PR_DESC_SOCKET_UDP &&
-      (int)datagram.get_length() > maximum_udp_datagram) {
+  if ((int)datagram.get_length() > maximum_udp_datagram) {
     net_cat.warning()
     net_cat.warning()
       << "Attempt to send UDP datagram of " << datagram.get_length()
       << "Attempt to send UDP datagram of " << datagram.get_length()
       << " bytes, more than the\n"
       << " bytes, more than the\n"
@@ -299,19 +307,6 @@ clear_manager() {
   _manager = (ConnectionManager *)NULL;
   _manager = (ConnectionManager *)NULL;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: ConnectionWriter::thread_start
-//       Access: Private, Static
-//  Description: The static wrapper around the thread's executing
-//               function.  This must be a static member function
-//               because it is passed through the C interface to
-//               PR_CreateThread().
-////////////////////////////////////////////////////////////////////
-void ConnectionWriter::
-thread_start(void *data) {
-  ((ConnectionWriter *)data)->thread_run();
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ConnectionWriter::thread_run
 //     Function: ConnectionWriter::thread_run
 //       Access: Private
 //       Access: Private
@@ -319,7 +314,7 @@ thread_start(void *data) {
 //               thread.
 //               thread.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ConnectionWriter::
 void ConnectionWriter::
-thread_run() {
+thread_run(int thread_index) {
   nassertv(!_immediate);
   nassertv(!_immediate);
 
 
   NetDatagram datagram;
   NetDatagram datagram;

+ 16 - 9
panda/src/net/connectionWriter.h

@@ -20,13 +20,10 @@
 #define CONNECTIONWRITER_H
 #define CONNECTIONWRITER_H
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-
 #include "datagramQueue.h"
 #include "datagramQueue.h"
 #include "connection.h"
 #include "connection.h"
-
 #include "pointerTo.h"
 #include "pointerTo.h"
-
-#include <prthread.h>
+#include "thread.h"
 #include "pvector.h"
 #include "pvector.h"
 
 
 class ConnectionManager;
 class ConnectionManager;
@@ -38,7 +35,7 @@ class NetAddress;
 //               various TCP or UDP sockets.
 //               various TCP or UDP sockets.
 //
 //
 //               A ConnectionWriter may define an arbitrary number of
 //               A ConnectionWriter may define an arbitrary number of
-//               threads (at least one) to write its datagrams to
+//               threads (0 or more) to write its datagrams to
 //               sockets.  The number of threads is specified at
 //               sockets.  The number of threads is specified at
 //               construction time and cannot be changed.
 //               construction time and cannot be changed.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -70,8 +67,7 @@ protected:
   void clear_manager();
   void clear_manager();
 
 
 private:
 private:
-  static void thread_start(void *data);
-  void thread_run();
+  void thread_run(int thread_index);
   bool send_datagram(const NetDatagram &datagram);
   bool send_datagram(const NetDatagram &datagram);
 
 
 protected:
 protected:
@@ -82,11 +78,22 @@ private:
   int _tcp_header_size;
   int _tcp_header_size;
   DatagramQueue _queue;
   DatagramQueue _queue;
 
 
-  typedef pvector<PRThread *> Threads;
+  class WriterThread : public Thread {
+  public:
+    WriterThread(ConnectionWriter *writer, int thread_index);
+    virtual void thread_main();
+
+    ConnectionWriter *_writer;
+    int _thread_index;
+  };
+
+  typedef pvector< PT(WriterThread) > Threads;
   Threads _threads;
   Threads _threads;
+
   bool _immediate;
   bool _immediate;
 
 
-friend class ConnectionManager;
+  friend class ConnectionManager;
+  friend class WriterThread;
 };
 };
 
 
 #endif
 #endif

+ 14 - 30
panda/src/net/datagramQueue.cxx

@@ -18,6 +18,7 @@
 
 
 #include "datagramQueue.h"
 #include "datagramQueue.h"
 #include "config_net.h"
 #include "config_net.h"
+#include "mutexHolder.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DatagramQueue::Constructor
 //     Function: DatagramQueue::Constructor
@@ -25,10 +26,8 @@
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 DatagramQueue::
 DatagramQueue::
-DatagramQueue() {
+DatagramQueue() : _cv(_cvlock) {
   _shutdown = false;
   _shutdown = false;
-  _cvlock = PR_NewLock();
-  _cv = PR_NewCondVar(_cvlock);
   _max_queue_size = get_net_max_write_queue();
   _max_queue_size = get_net_max_write_queue();
 }
 }
 
 
@@ -42,9 +41,6 @@ DatagramQueue::
   // It's an error to delete a DatagramQueue without first shutting it
   // It's an error to delete a DatagramQueue without first shutting it
   // down (and waiting for any associated threads to terminate).
   // down (and waiting for any associated threads to terminate).
   nassertv(_shutdown);
   nassertv(_shutdown);
-
-  PR_DestroyCondVar(_cv);
-  PR_DestroyLock(_cvlock);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -61,10 +57,10 @@ void DatagramQueue::
 shutdown() {
 shutdown() {
   // Notify all of our threads that we're shutting down.  This will
   // Notify all of our threads that we're shutting down.  This will
   // cause any thread blocking on extract() to return false.
   // cause any thread blocking on extract() to return false.
-  PR_Lock(_cvlock);
+  MutexHolder holder(_cvlock);
+
   _shutdown = true;
   _shutdown = true;
-  PR_NotifyAllCondVar(_cv);
-  PR_Unlock(_cvlock);
+  _cv.signal_all();
 }
 }
 
 
 
 
@@ -79,17 +75,14 @@ shutdown() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DatagramQueue::
 bool DatagramQueue::
 insert(const NetDatagram &data) {
 insert(const NetDatagram &data) {
-  PR_Lock(_cvlock);
+  MutexHolder holder(_cvlock);
+
   bool enqueue_ok = ((int)_queue.size() < _max_queue_size);
   bool enqueue_ok = ((int)_queue.size() < _max_queue_size);
   if (enqueue_ok) {
   if (enqueue_ok) {
-#ifdef __ICL
-    _queue.push_back(new NetDatagram(data));
-#else
     _queue.push_back(data);
     _queue.push_back(data);
-#endif
   }
   }
-  PR_NotifyCondVar(_cv);
-  PR_Unlock(_cvlock);
+  _cv.signal();
+
   return enqueue_ok;
   return enqueue_ok;
 }
 }
 
 
@@ -118,27 +111,20 @@ extract(NetDatagram &result) {
   // connection pointer--we're about to go to sleep for a while.
   // connection pointer--we're about to go to sleep for a while.
   result.clear();
   result.clear();
 
 
-  PR_Lock(_cvlock);
+  MutexHolder holder(_cvlock);
+
   while (_queue.empty() && !_shutdown) {
   while (_queue.empty() && !_shutdown) {
-    PR_WaitCondVar(_cv, PR_INTERVAL_NO_TIMEOUT);
+    _cv.wait();
   }
   }
 
 
   if (_shutdown) {
   if (_shutdown) {
-    PR_Unlock(_cvlock);
     return false;
     return false;
   }
   }
 
 
   nassertr(!_queue.empty(), false);
   nassertr(!_queue.empty(), false);
-#ifdef __ICL
-  NetDatagram *ptr = _queue.front();
-  result = *ptr;
-  delete ptr;
-#else
   result = _queue.front();
   result = _queue.front();
-#endif
   _queue.pop_front();
   _queue.pop_front();
 
 
-  PR_Unlock(_cvlock);
   return true;
   return true;
 }
 }
 
 
@@ -156,9 +142,8 @@ extract(NetDatagram &result) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DatagramQueue::
 void DatagramQueue::
 set_max_queue_size(int max_size) {
 set_max_queue_size(int max_size) {
-  PR_Lock(_cvlock);
+  MutexHolder holder(_cvlock);
   _max_queue_size = max_size;
   _max_queue_size = max_size;
-  PR_Unlock(_cvlock);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -179,8 +164,7 @@ get_max_queue_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 int DatagramQueue::
 int DatagramQueue::
 get_current_queue_size() const {
 get_current_queue_size() const {
-  PR_Lock(_cvlock);
+  MutexHolder holder(_cvlock);
   int size = _queue.size();
   int size = _queue.size();
-  PR_Unlock(_cvlock);
   return size;
   return size;
 }
 }

+ 4 - 12
panda/src/net/datagramQueue.h

@@ -22,9 +22,8 @@
 #include "pandabase.h"
 #include "pandabase.h"
 
 
 #include "netDatagram.h"
 #include "netDatagram.h"
-
-#include <prlock.h>
-#include <prcvar.h>
+#include "pmutex.h"
+#include "conditionVarFull.h"
 #include "pdeque.h"
 #include "pdeque.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -47,17 +46,10 @@ public:
   int get_current_queue_size() const;
   int get_current_queue_size() const;
 
 
 private:
 private:
-  PRLock *_cvlock;
-  PRCondVar *_cv;
+  Mutex _cvlock;
+  ConditionVarFull _cv;
 
 
-#ifdef __ICL
-  // The Intel compiler for some reason dumps core on a queue of
-  // NetDatagrams.
-  typedef pdeque<NetDatagram *> QueueType;
-#else
   typedef pdeque<NetDatagram> QueueType;
   typedef pdeque<NetDatagram> QueueType;
-#endif
-
   QueueType _queue;
   QueueType _queue;
   bool _shutdown;
   bool _shutdown;
   int _max_queue_size;
   int _max_queue_size;

+ 2 - 2
panda/src/net/datagramTCPHeader.cxx

@@ -38,7 +38,7 @@ DatagramTCPHeader(const NetDatagram &datagram, int header_size) {
 
 
   case datagram_tcp16_header_size:
   case datagram_tcp16_header_size:
     {
     {
-      PRUint16 size = str.length();
+      PN_uint16 size = str.length();
       nassertv(size == str.length());
       nassertv(size == str.length());
       _header.add_uint16(size);
       _header.add_uint16(size);
     }
     }
@@ -46,7 +46,7 @@ DatagramTCPHeader(const NetDatagram &datagram, int header_size) {
 
 
   case datagram_tcp32_header_size:
   case datagram_tcp32_header_size:
     {
     {
-      PRUint32 size = str.length();
+      PN_uint32 size = str.length();
       nassertv(size == str.length());
       nassertv(size == str.length());
       _header.add_uint32(size);
       _header.add_uint32(size);
     }
     }

+ 3 - 4
panda/src/net/datagramTCPHeader.h

@@ -24,11 +24,10 @@
 #include "netDatagram.h"
 #include "netDatagram.h"
 
 
 #include "datagramIterator.h"
 #include "datagramIterator.h"
+#include "numeric_types.h"
 
 
-#include <prtypes.h>
-
-static const int datagram_tcp16_header_size = sizeof(PRUint16);
-static const int datagram_tcp32_header_size = sizeof(PRUint32);
+static const int datagram_tcp16_header_size = sizeof(PN_uint16);
+static const int datagram_tcp32_header_size = sizeof(PN_uint32);
 
 
 class NetDatagram;
 class NetDatagram;
 
 

+ 4 - 4
panda/src/net/datagramUDPHeader.cxx

@@ -32,9 +32,9 @@
 DatagramUDPHeader::
 DatagramUDPHeader::
 DatagramUDPHeader(const NetDatagram &datagram) {
 DatagramUDPHeader(const NetDatagram &datagram) {
   const string &str = datagram.get_message();
   const string &str = datagram.get_message();
-  PRUint16 checksum = 0;
+  PN_uint16 checksum = 0;
   for (size_t p = 0; p < str.size(); p++) {
   for (size_t p = 0; p < str.size(); p++) {
-    checksum += (PRUint16)(PRUint8)str[p];
+    checksum += (PN_uint16)(PN_uint8)str[p];
   }
   }
 
 
   // Now pack the header.
   // Now pack the header.
@@ -64,9 +64,9 @@ bool DatagramUDPHeader::
 verify_datagram(const NetDatagram &datagram) const {
 verify_datagram(const NetDatagram &datagram) const {
   const string &str = datagram.get_message();
   const string &str = datagram.get_message();
 
 
-  PRUint16 checksum = 0;
+  PN_uint16 checksum = 0;
   for (size_t p = 0; p < str.size(); p++) {
   for (size_t p = 0; p < str.size(); p++) {
-    checksum += (PRUint16)(PRUint8)str[p];
+    checksum += (PN_uint16)(PN_uint8)str[p];
   }
   }
 
 
   if (checksum == get_datagram_checksum()) {
   if (checksum == get_datagram_checksum()) {

+ 2 - 3
panda/src/net/datagramUDPHeader.h

@@ -24,10 +24,9 @@
 #include "netDatagram.h"
 #include "netDatagram.h"
 
 
 #include "datagramIterator.h"
 #include "datagramIterator.h"
+#include "numeric_types.h"
 
 
-#include <prtypes.h>
-
-static const int datagram_udp_header_size = sizeof(PRUint16);
+static const int datagram_udp_header_size = sizeof(PN_uint16);
 
 
 class NetDatagram;
 class NetDatagram;
 
 

+ 15 - 116
panda/src/net/netAddress.cxx

@@ -17,12 +17,8 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 #include "netAddress.h"
 #include "netAddress.h"
-#include "pprerror.h"
 #include "config_net.h"
 #include "config_net.h"
 
 
-#include <prio.h>
-#include <prnetdb.h>
-
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::Constructor
 //     Function: NetAddress::Constructor
@@ -31,19 +27,18 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 NetAddress::
 NetAddress::
 NetAddress() {
 NetAddress() {
-  PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &_addr);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::Constructor
 //     Function: NetAddress::Constructor
 //       Access: Public
 //       Access: Public
-//  Description: Constructs an address from a given PRNetAddr.
+//  Description: Constructs an address from a given Socket_Address.
 //               Normally, this constructor should not be used by user
 //               Normally, this constructor should not be used by user
 //               code; instead, create a default NetAddress and use
 //               code; instead, create a default NetAddress and use
 //               one of the set_*() functions to set up an address.
 //               one of the set_*() functions to set up an address.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 NetAddress::
 NetAddress::
-NetAddress(const PRNetAddr &addr) : _addr(addr) {
+NetAddress(const Socket_Address &addr) : _addr(addr) {
 }
 }
 
 
 
 
@@ -57,9 +52,7 @@ NetAddress(const PRNetAddr &addr) : _addr(addr) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NetAddress::
 bool NetAddress::
 set_any(int port) {
 set_any(int port) {
-  PR_InitializeNetAddr(PR_IpAddrAny, port, &_addr);
-
-  return true;
+  return _addr.set_any_IP(port);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -70,9 +63,7 @@ set_any(int port) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NetAddress::
 bool NetAddress::
 set_localhost(int port) {
 set_localhost(int port) {
-  PR_InitializeNetAddr(PR_IpAddrLoopback, port, &_addr);
-
-  return true;
+  return _addr.set_host("127.0.0.1", port);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -84,90 +75,7 @@ set_localhost(int port) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NetAddress::
 bool NetAddress::
 set_host(const string &hostname, int port) {
 set_host(const string &hostname, int port) {
-  // If the hostname appears to be a dot-separated IPv4 address, then
-  // parse it directly and store it.  Some OS system libraries
-  // (notably Win95) can't parse this themselves.
-  union {
-    PRUint32 l;
-    unsigned char n[4];
-  } ipaddr;
-  int ni = 0;
-  bool is_ip = true;
-  size_t p = 0;
-  size_t q = 0;
-  unsigned int num = 0;
-
-  while (p < hostname.length() && ni < 4 && is_ip) {
-    if (hostname[p] == '.' && p > q) {
-      // Now we have a number between q and p.
-      ipaddr.n[ni] = (unsigned char)num;
-      p++;
-      q = p;
-      num = 0;
-      ni++;
-
-      if (num >= 256 || ni >= 4) {
-        is_ip = false;
-      }
-
-    } else if (isdigit(hostname[p])) {
-      num = 10 * num + (unsigned int)(hostname[p] - '0');
-      p++;
-      if (num >= 256) {
-        is_ip = false;
-      }
-    } else {
-      is_ip = false;
-    }
-  }
-
-  if (p == hostname.length() && ni < 4 && is_ip && p > q) {
-    ipaddr.n[ni] = (unsigned char)num;
-    ni++;
-
-    if (num >= 256) {
-      is_ip = false;
-    }
-  }
-
-  if (p == hostname.length() && ni == 4 && is_ip) {
-    net_cat.debug()
-      << "Parsed IP " << (int)ipaddr.n[0] << "." << (int)ipaddr.n[1]
-      << "." << (int)ipaddr.n[2] << "." << (int)ipaddr.n[3] << "\n";
-
-    memset(&_addr, 0, sizeof(PRNetAddr));
-    _addr.inet.family = PR_AF_INET;
-    _addr.inet.port = PR_htons(port);
-    _addr.inet.ip = ipaddr.l;
-
-  } else {
-    // If it's not a numeric IPv4 address, pass the whole thing on to
-    // GetHostByName and let NSPR deal with it.
-
-    char buf[PR_NETDB_BUF_SIZE];
-    PRHostEnt host;
-    PRStatus result =
-      PR_GetHostByName(hostname.c_str(), buf, PR_NETDB_BUF_SIZE, &host);
-    if (result != PR_SUCCESS) {
-      pprerror("PR_GetHostByName");
-      net_cat.error()
-        << "Unable to look up hostname " << hostname << ".\n";
-      return false;
-    }
-
-    PRIntn next = PR_EnumerateHostEnt(0, &host, port, &_addr);
-
-    if (next == -1) {
-      pprerror("PR_EnumerateHostEnt");
-      return false;
-    } else if (next == 0) {
-      net_cat.error()
-        << "No addresses available for " << hostname << ".\n";
-      return false;
-    }
-  }
-
-  return true;
+  return _addr.set_host(hostname, port);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -177,7 +85,7 @@ set_host(const string &hostname, int port) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void NetAddress::
 void NetAddress::
 clear() {
 clear() {
-  PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &_addr);
+  _addr.clear();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -187,7 +95,7 @@ clear() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 int NetAddress::
 int NetAddress::
 get_port() const {
 get_port() const {
-  return PR_ntohs(_addr.inet.port);
+  return _addr.get_port();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -198,7 +106,7 @@ get_port() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void NetAddress::
 void NetAddress::
 set_port(int port) {
 set_port(int port) {
-  PR_InitializeNetAddr(PR_IpAddrNull, port, &_addr);
+  _addr.set_port(port);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -209,17 +117,7 @@ set_port(int port) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 string NetAddress::
 string NetAddress::
 get_ip_string() const {
 get_ip_string() const {
-  static const int buf_len = 1024;
-  char buf[buf_len];
-
-  PRStatus result =
-    PR_NetAddrToString(&_addr, buf, buf_len);
-  if (result != PR_SUCCESS) {
-    pprerror("PR_NetAddrToString");
-    return "error";
-  }
-
-  return string(buf);
+  return _addr.get_ip();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -230,7 +128,7 @@ get_ip_string() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PN_uint32 NetAddress::
 PN_uint32 NetAddress::
 get_ip() const {
 get_ip() const {
-  return PR_ntohl(_addr.inet.ip);
+  return _addr.GetIPAddressRaw();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -244,7 +142,8 @@ get_ip() const {
 PN_uint8 NetAddress::
 PN_uint8 NetAddress::
 get_ip_component(int n) const {
 get_ip_component(int n) const {
   nassertr(n >= 0 && n < 4, 0);
   nassertr(n >= 0 && n < 4, 0);
-  const PN_uint8 *ip = (const PN_uint8 *)&_addr.inet.ip;
+  PN_uint32 ip_long = _addr.GetIPAddressRaw();
+  const PN_uint8 *ip = (const PN_uint8 *)&ip_long;
   return ip[n];
   return ip[n];
 }
 }
 
 
@@ -252,11 +151,11 @@ get_ip_component(int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NetAddress::get_addr
 //     Function: NetAddress::get_addr
 //       Access: Public
 //       Access: Public
-//  Description: Returns the PRNetAddr for this address.
+//  Description: Returns the Socket_Address for this address.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-PRNetAddr *NetAddress::
+const Socket_Address &NetAddress::
 get_addr() const {
 get_addr() const {
-  return (PRNetAddr *)&_addr;
+  return _addr;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 5
panda/src/net/netAddress.h

@@ -21,8 +21,7 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 #include "numeric_types.h"
 #include "numeric_types.h"
-
-#include <prio.h>
+#include "socket_address.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : NetAddress
 //       Class : NetAddress
@@ -32,7 +31,7 @@
 class EXPCL_PANDA NetAddress {
 class EXPCL_PANDA NetAddress {
 PUBLISHED:
 PUBLISHED:
   NetAddress();
   NetAddress();
-  NetAddress(const PRNetAddr &addr);
+  NetAddress(const Socket_Address &addr);
 
 
   bool set_any(int port);
   bool set_any(int port);
   bool set_localhost(int port);
   bool set_localhost(int port);
@@ -46,12 +45,12 @@ PUBLISHED:
   PN_uint32 get_ip() const;
   PN_uint32 get_ip() const;
   PN_uint8 get_ip_component(int n) const;
   PN_uint8 get_ip_component(int n) const;
 
 
-  PRNetAddr *get_addr() const;
+  const Socket_Address &get_addr() const;
 
 
   void output(ostream &out) const;
   void output(ostream &out) const;
 
 
 private:
 private:
-  PRNetAddr _addr;
+  Socket_Address _addr;
 };
 };
 
 
 INLINE ostream &operator << (ostream &out, const NetAddress &addr) {
 INLINE ostream &operator << (ostream &out, const NetAddress &addr) {

+ 0 - 1
panda/src/net/net_composite1.cxx

@@ -1,6 +1,5 @@
 
 
 #include "config_net.cxx"
 #include "config_net.cxx"
-#include "pprerror.cxx"
 #include "connection.cxx"
 #include "connection.cxx"
 #include "connectionListener.cxx"
 #include "connectionListener.cxx"
 #include "connectionManager.cxx"
 #include "connectionManager.cxx"

+ 0 - 238
panda/src/net/pprerror.cxx

@@ -1,238 +0,0 @@
-// Filename: pprerror.cxx
-// Created by:  drose (08Feb00)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "pandabase.h"
-#include "pprerror.h"
-#include "config_net.h"
-
-#include <prerror.h>
-#include <prprf.h>
-#include <prmem.h>
-
-#include <stdarg.h>
-#include <stdio.h>
-
-static const char *get_error_message(PRErrorCode code);
-
-////////////////////////////////////////////////////////////////////
-//     Function: pprerror
-//  Description: A handy function like perror().  It outputs the
-//               printf-style format string and its arguments,
-//               followed by a colon and the NSPR-given description of
-//               its current error state.
-////////////////////////////////////////////////////////////////////
-void
-pprerror(const char *format, ...) {
-  va_list ap;
-  va_start(ap, format);
-
-  char *str = PR_vsprintf_append(NULL, format, ap);
-  if (str == (char *)NULL) {
-    net_cat.error()
-      << string("Invalid format string: ") + format + "\n";
-    return;
-  }
-
-  PRErrorCode code = PR_GetError();
-  const char *error_message = get_error_message(code);
-
-  if (error_message == (const char *)NULL) {
-    str = PR_sprintf_append(str, ": (%d)\n", code);
-  } else {
-    str = PR_sprintf_append(str, ": %s (%d)\n", error_message, code);
-  }
-
-  net_cat.error() << str;
-
-  PR_Free(str);
-  if (get_net_error_abort()) {
-    abort();
-  }
-  va_end(ap);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: get_error_message
-//  Description: A local function to this module, it returns a
-//               sensibly formatted string to describe the given NSPR
-//               error code.  The strings in this function were
-//               extracted from the NSPR documentation web site.
-////////////////////////////////////////////////////////////////////
-static const char *
-get_error_message(PRErrorCode code) {
-  switch (code) {
-  case PR_OUT_OF_MEMORY_ERROR:
-    return "PR_OUT_OF_MEMORY_ERROR--Insufficient memory to perform request.";
-  case PR_BAD_DESCRIPTOR_ERROR:
-    return "PR_BAD_DESCRIPTOR_ERROR--The file descriptor used as an argument in the preceding function is invalid.";
-  case PR_WOULD_BLOCK_ERROR:
-    return "PR_WOULD_BLOCK_ERROR--The operation would have blocked, which conflicts with the semantics that have been established.";
-  case PR_ACCESS_FAULT_ERROR:
-    return "PR_ACCESS_FAULT_ERROR--One of the arguments of the preceding function specified an invalid memory address.";
-  case PR_INVALID_METHOD_ERROR:
-    return "PR_INVALID_METHOD_ERROR--The preceding function is invalid for the type of file descriptor used.";
-  case PR_ILLEGAL_ACCESS_ERROR:
-    return "PR_ILLEGAL_ACCESS_ERROR--One of the arguments of the preceding function specified an invalid memory address.";
-  case PR_UNKNOWN_ERROR:
-    return "PR_UNKNOWN_ERROR--Some unknown error has occurred.";
-  case PR_PENDING_INTERRUPT_ERROR:
-    return "PR_PENDING_INTERRUPT_ERROR--The operation terminated because another thread has interrupted it with PR_Interrupt.";
-  case PR_NOT_IMPLEMENTED_ERROR:
-    return "PR_NOT_IMPLEMENTED_ERROR--The preceding function has not been implemented.";
-  case PR_IO_ERROR:
-    return "PR_IO_ERROR--The preceding I/O function encountered some sort of an error, perhaps an invalid device.";
-  case PR_IO_TIMEOUT_ERROR:
-    return "PR_IO_TIMEOUT_ERROR--The I/O operation has not completed in the time specified for the preceding function.";
-  case PR_IO_PENDING_ERROR:
-    return "PR_IO_PENDING_ERROR--An I/O operation has been attempted on a file descriptor that is currently busy with another operation.";
-  case PR_DIRECTORY_OPEN_ERROR:
-    return "PR_DIRECTORY_OPEN_ERROR--The directory could not be opened.";
-  case PR_INVALID_ARGUMENT_ERROR:
-    return "PR_INVALID_ARGUMENT_ERROR--One or more of the arguments to the function is invalid.";
-  case PR_ADDRESS_NOT_AVAILABLE_ERROR:
-    return "PR_ADDRESS_NOT_AVAILABLE_ERROR--The network address (PRNetAddr) is not available (probably in use).";
-  case PR_ADDRESS_NOT_SUPPORTED_ERROR:
-    return "PR_ADDRESS_NOT_SUPPORTED_ERROR--The type of network address specified is not supported.";
-  case PR_IS_CONNECTED_ERROR:
-    return "PR_IS_CONNECTED_ERROR--An attempt to connect on an already connected network file descriptor.";
-  case PR_BAD_ADDRESS_ERROR:
-    return "PR_BAD_ADDRESS_ERROR--The network address specified is invalid (as reported by the network).";
-  case PR_ADDRESS_IN_USE_ERROR:
-    return "PR_ADDRESS_IN_USE_ERROR--Network address specified (PRNetAddr) is in use.";
-  case PR_CONNECT_REFUSED_ERROR:
-    return "PR_CONNECT_REFUSED_ERROR--The peer has refused to allow the connection to be established.";
-  case PR_NETWORK_UNREACHABLE_ERROR:
-    return "PR_NETWORK_UNREACHABLE_ERROR--The network address specifies a host that is unreachable (perhaps temporary).";
-  case PR_CONNECT_TIMEOUT_ERROR:
-    return "PR_CONNECT_TIMEOUT_ERROR--The connection attempt did not complete in a reasonable period of time.";
-  case PR_NOT_CONNECTED_ERROR:
-    return "PR_NOT_CONNECTED_ERROR--The preceding function attempted to use connected semantics on a network file descriptor that was not connected.";
-  case PR_LOAD_LIBRARY_ERROR:
-    return "PR_LOAD_LIBRARY_ERROR--Failure to load a dynamic library.";
-  case PR_UNLOAD_LIBRARY_ERROR:
-    return "PR_UNLOAD_LIBRARY_ERROR--Failure to unload a dynamic library.";
-  case PR_FIND_SYMBOL_ERROR:
-    return "PR_FIND_SYMBOL_ERROR--Symbol could not be found in the specified library.";
-  case PR_INSUFFICIENT_RESOURCES_ERROR:
-    return "PR_INSUFFICIENT_RESOURCES_ERROR--There are insufficient system resources to process the request.";
-  case PR_DIRECTORY_LOOKUP_ERROR:
-    return "PR_DIRECTORY_LOOKUP_ERROR--A directory lookup on a network address has failed.";
-  case PR_TPD_RANGE_ERROR:
-    return "PR_TPD_RANGE_ERROR--Attempt to access a thread-private data index that is out of range of any index that has been allocated to the process.";
-  case PR_PROC_DESC_TABLE_FULL_ERROR:
-    return "PR_PROC_DESC_TABLE_FULL_ERROR--The process' table for holding open file descriptors is full.";
-  case PR_SYS_DESC_TABLE_FULL_ERROR:
-    return "PR_SYS_DESC_TABLE_FULL_ERROR--The system's table for holding open file descriptors has been exceeded.";
-  case PR_NOT_SOCKET_ERROR:
-    return "PR_NOT_SOCKET_ERROR--An attempt to use a non-network file descriptor on a network-only operation.";
-  case PR_NOT_TCP_SOCKET_ERROR:
-    return "PR_NOT_TCP_SOCKET_ERROR--Attempt to perform a TCP specific function on a non-TCP file descriptor.";
-  case PR_SOCKET_ADDRESS_IS_BOUND_ERROR:
-    return "PR_SOCKET_ADDRESS_IS_BOUND_ERROR--Attempt to bind an address to a TCP file descriptor that is already bound.";
-  case PR_NO_ACCESS_RIGHTS_ERROR:
-    return "PR_NO_ACCESS_RIGHTS_ERROR--Calling thread does not have privilege to perform the operation requested.";
-  case PR_OPERATION_NOT_SUPPORTED_ERROR:
-    return "PR_OPERATION_NOT_SUPPORTED_ERROR--The requested operation is not supported by the platform.";
-  case PR_PROTOCOL_NOT_SUPPORTED_ERROR:
-    return "PR_PROTOCOL_NOT_SUPPORTED_ERROR--The host operating system does not support the protocol requested.";
-  case PR_REMOTE_FILE_ERROR:
-    return "PR_REMOTE_FILE_ERROR--Access to the remote file has been severed.";
-  case PR_BUFFER_OVERFLOW_ERROR:
-    return "PR_BUFFER_OVERFLOW_ERROR--The value retrieved is too large to be stored in the buffer provided.";
-  case PR_CONNECT_RESET_ERROR:
-    return "PR_CONNECT_RESET_ERROR--The (TCP) connection has been reset by the peer.";
-  case PR_RANGE_ERROR:
-    return "PR_RANGE_ERROR--Unused.";
-  case PR_DEADLOCK_ERROR:
-    return "PR_DEADLOCK_ERROR--Performing the requested operation would have caused a deadlock. The deadlock was avoided.";
-  case PR_FILE_IS_LOCKED_ERROR:
-    return "PR_FILE_IS_LOCKED_ERROR--An attempt to acquire a lock on a file has failed because the file is already locked.";
-  case PR_FILE_TOO_BIG_ERROR:
-    return "PR_FILE_TOO_BIG_ERROR--Completing the write or seek operation would have resulted in a file larger than the system could handle.";
-  case PR_NO_DEVICE_SPACE_ERROR:
-    return "PR_NO_DEVICE_SPACE_ERROR--The device for storing the file is full.";
-  case PR_PIPE_ERROR:
-    return "PR_PIPE_ERROR--Unused.";
-  case PR_NO_SEEK_DEVICE_ERROR:
-    return "PR_NO_SEEK_DEVICE_ERROR--Unused.";
-  case PR_IS_DIRECTORY_ERROR:
-    return "PR_IS_DIRECTORY_ERROR--Attempt to perform a normal file operation on a directory.";
-  case PR_LOOP_ERROR:
-    return "PR_LOOP_ERROR--Symbolic link loop.";
-  case PR_NAME_TOO_LONG_ERROR:
-    return "PR_NAME_TOO_LONG_ERROR--Filename is longer than allowed by the host operating system.";
-  case PR_FILE_NOT_FOUND_ERROR:
-    return "PR_FILE_NOT_FOUND_ERROR--The requested file was not found.";
-  case PR_NOT_DIRECTORY_ERROR:
-    return "PR_NOT_DIRECTORY_ERROR--Attempt to perform directory specific operations on a normal file.";
-  case PR_READ_ONLY_FILESYSTEM_ERROR:
-    return "PR_READ_ONLY_FILESYSTEM_ERROR--Attempt to write to a read-only file system.";
-  case PR_DIRECTORY_NOT_EMPTY_ERROR:
-    return "PR_DIRECTORY_NOT_EMPTY_ERROR--Attempt to delete a directory that is not empty.";
-  case PR_FILESYSTEM_MOUNTED_ERROR:
-    return "PR_FILESYSTEM_MOUNTED_ERROR--Attempt to delete or rename a file object while the file system is busy.";
-  case PR_NOT_SAME_DEVICE_ERROR:
-    return "PR_NOT_SAME_DEVICE_ERROR--Request to rename a file to a file system on another device.";
-  case PR_DIRECTORY_CORRUPTED_ERROR:
-    return "PR_DIRECTORY_CORRUPTED_ERROR--The directory object in the file system is corrupted.";
-  case PR_FILE_EXISTS_ERROR:
-    return "PR_FILE_EXISTS_ERROR--Attempt to create or rename a file when the new name is already being used.";
-  case PR_MAX_DIRECTORY_ENTRIES_ERROR:
-    return "PR_MAX_DIRECTORY_ENTRIES_ERROR--Attempt to add new filename to directory would exceed the limit allowed.";
-  case PR_INVALID_DEVICE_STATE_ERROR:
-    return "PR_INVALID_DEVICE_STATE_ERROR--The device was in an invalid state to complete the desired operation.";
-  case PR_DEVICE_IS_LOCKED_ERROR:
-    return "PR_DEVICE_IS_LOCKED_ERROR--The device needed to perform the desired request is locked.";
-  case PR_NO_MORE_FILES_ERROR:
-    return "PR_NO_MORE_FILES_ERROR--There are no more entries in the directory.";
-  case PR_END_OF_FILE_ERROR:
-    return "PR_END_OF_FILE_ERROR--Unexpectedly encountered end of file (Mac OS only).";
-  case PR_FILE_SEEK_ERROR:
-    return "PR_FILE_SEEK_ERROR--An unexpected seek error (Mac OS only).";
-  case PR_FILE_IS_BUSY_ERROR:
-    return "PR_FILE_IS_BUSY_ERROR--The file is busy and the operation cannot be performed (Mac OS only).";
-  case PR_IN_PROGRESS_ERROR:
-    return "PR_IN_PROGRESS_ERROR--The operation is still in progress (probably a nonblocking connect).";
-  case PR_ALREADY_INITIATED_ERROR:
-    return "PR_ALREADY_INITIATED_ERROR--The (retried) operation has already been initiated (probably a nonblocking connect).";
-  case PR_GROUP_EMPTY_ERROR:
-    return "PR_GROUP_EMPTY_ERROR--The wait group is empty.";
-  case PR_INVALID_STATE_ERROR:
-    return "PR_INVALID_STATE_ERROR--The attempted operation is on an object that was in an improper state to perform the request.";
-
-    // These were added with NSPR 4.0.
-#ifdef PR_NETWORK_DOWN_ERROR
-  case PR_NETWORK_DOWN_ERROR:
-    return "PR_NETWORK_DOWN_ERROR--The network is down.";
-
-  case PR_SOCKET_SHUTDOWN_ERROR:
-    return "PR_SOCKET_SHUTDOWN_ERROR--The socket has been shut down.";
-
-  case PR_CONNECT_ABORTED_ERROR:
-    return "PR_CONNECT_ABORTED_ERROR--The connection has been aborted.";
-
-  case PR_HOST_UNREACHABLE_ERROR:
-    return "PR_HOST_UNREACHABLE_ERROR--The host is unreachable.";
-#endif
-
-  case PR_MAX_ERROR:
-    return "PR_MAX_ERROR--Placeholder for the end of the list.";
-  }
-
-  return (const char *)NULL;
-}

+ 0 - 2
panda/src/net/queuedConnectionListener.h

@@ -25,8 +25,6 @@
 #include "connection.h"
 #include "connection.h"
 #include "netAddress.h"
 #include "netAddress.h"
 #include "queuedReturn.h"
 #include "queuedReturn.h"
-
-#include <prlock.h>
 #include "pdeque.h"
 #include "pdeque.h"
 
 
 
 

+ 2 - 2
panda/src/net/queuedConnectionManager.cxx

@@ -98,8 +98,8 @@ get_reset_connection(PT(Connection) &connection) {
 //               been reset.
 //               been reset.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void QueuedConnectionManager::
 void QueuedConnectionManager::
-connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
-  ConnectionManager::connection_reset(connection, errcode);
+connection_reset(const PT(Connection) &connection, bool okflag) {
+  ConnectionManager::connection_reset(connection, okflag);
 
 
   // Largely, we don't care if this particular queue fills up.  If it
   // Largely, we don't care if this particular queue fills up.  If it
   // does, it probably just means the user isn't bothering to track
   // does, it probably just means the user isn't bothering to track

+ 1 - 3
panda/src/net/queuedConnectionManager.h

@@ -25,8 +25,6 @@
 #include "queuedReturn.h"
 #include "queuedReturn.h"
 #include "pdeque.h"
 #include "pdeque.h"
 
 
-#include <prlock.h>
-
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, QueuedReturn< PT(Connection) >);
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, QueuedReturn< PT(Connection) >);
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -53,7 +51,7 @@ PUBLISHED:
 
 
 protected:
 protected:
   virtual void connection_reset(const PT(Connection) &connection, 
   virtual void connection_reset(const PT(Connection) &connection, 
-                                PRErrorCode errcode);
+                                bool okflag);
 };
 };
 
 
 #endif
 #endif

+ 5 - 14
panda/src/net/queuedConnectionReader.cxx

@@ -19,6 +19,7 @@
 #include "queuedConnectionReader.h"
 #include "queuedConnectionReader.h"
 #include "config_net.h"
 #include "config_net.h"
 #include "trueClock.h"
 #include "trueClock.h"
+#include "mutexHolder.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: QueuedConnectionReader::Constructor
 //     Function: QueuedConnectionReader::Constructor
@@ -30,7 +31,6 @@ QueuedConnectionReader(ConnectionManager *manager, int num_threads) :
   ConnectionReader(manager, num_threads)
   ConnectionReader(manager, num_threads)
 {
 {
 #ifdef SIMULATE_NETWORK_DELAY
 #ifdef SIMULATE_NETWORK_DELAY
-  _dd_mutex = PR_NewLock();
   _delay_active = false;
   _delay_active = false;
   _min_delay = 0.0;
   _min_delay = 0.0;
   _delay_variance = 0.0;
   _delay_variance = 0.0;
@@ -47,10 +47,6 @@ QueuedConnectionReader::
   // We call shutdown() here to guarantee that all threads are gone
   // We call shutdown() here to guarantee that all threads are gone
   // before the QueuedReturn destructs.
   // before the QueuedReturn destructs.
   shutdown();
   shutdown();
-
-#ifdef SIMULATE_NETWORK_DELAY
-  PR_DestroyLock(_dd_mutex);
-#endif  // SIMULATE_NETWORK_DELAY
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -149,11 +145,10 @@ receive_datagram(const NetDatagram &datagram) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void QueuedConnectionReader::
 void QueuedConnectionReader::
 start_delay(double min_delay, double max_delay) {
 start_delay(double min_delay, double max_delay) {
-  PR_Lock(_dd_mutex);
+  MutexHolder holder(_dd_mutex);
   _min_delay = min_delay;
   _min_delay = min_delay;
   _delay_variance = max(max_delay - min_delay, 0.0);
   _delay_variance = max(max_delay - min_delay, 0.0);
   _delay_active = true;
   _delay_active = true;
-  PR_Unlock(_dd_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -165,7 +160,7 @@ start_delay(double min_delay, double max_delay) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void QueuedConnectionReader::
 void QueuedConnectionReader::
 stop_delay() {
 stop_delay() {
-  PR_Lock(_dd_mutex);
+  MutexHolder holder(_dd_mutex);
   _delay_active = false;
   _delay_active = false;
 
 
   // Copy the entire contents of the delay queue to the normal queue.
   // Copy the entire contents of the delay queue to the normal queue.
@@ -177,8 +172,6 @@ stop_delay() {
     }
     }
     _delayed.pop_front();
     _delayed.pop_front();
   }
   }
-    
-  PR_Unlock(_dd_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -191,7 +184,7 @@ stop_delay() {
 void QueuedConnectionReader::
 void QueuedConnectionReader::
 get_delayed() {
 get_delayed() {
   if (_delay_active) {
   if (_delay_active) {
-    PR_Lock(_dd_mutex);
+    MutexHolder holder(_dd_mutex);
     double now = TrueClock::get_global_ptr()->get_short_time();
     double now = TrueClock::get_global_ptr()->get_short_time();
     while (!_delayed.empty()) {
     while (!_delayed.empty()) {
       const DelayedDatagram &dd = _delayed.front();
       const DelayedDatagram &dd = _delayed.front();
@@ -205,7 +198,6 @@ get_delayed() {
       }
       }
       _delayed.pop_front();
       _delayed.pop_front();
     }
     }
-    PR_Unlock(_dd_mutex);
   }
   }
 }
 }
 
 
@@ -223,7 +215,7 @@ delay_datagram(const NetDatagram &datagram) {
         << "QueuedConnectionReader queue full!\n";
         << "QueuedConnectionReader queue full!\n";
     }
     }
   } else {
   } else {
-    PR_Lock(_dd_mutex);
+    MutexHolder holder(_dd_mutex);
     // Check the delay_active flag again, now that we have grabbed the
     // Check the delay_active flag again, now that we have grabbed the
     // mutex.
     // mutex.
     if (!_delay_active) {
     if (!_delay_active) {
@@ -244,7 +236,6 @@ delay_datagram(const NetDatagram &datagram) {
       dd._reveal_time = reveal_time;
       dd._reveal_time = reveal_time;
       dd._datagram = datagram;
       dd._datagram = datagram;
     }
     }
-    PR_Unlock(_dd_mutex);
   }
   }
 }
 }
 
 

+ 2 - 3
panda/src/net/queuedConnectionReader.h

@@ -24,8 +24,7 @@
 #include "connectionReader.h"
 #include "connectionReader.h"
 #include "netDatagram.h"
 #include "netDatagram.h"
 #include "queuedReturn.h"
 #include "queuedReturn.h"
-
-#include <prlock.h>
+#include "pmutex.h"
 #include "pdeque.h"
 #include "pdeque.h"
 
 
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, QueuedReturn<NetDatagram>);
 EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, QueuedReturn<NetDatagram>);
@@ -67,7 +66,7 @@ private:
     NetDatagram _datagram;
     NetDatagram _datagram;
   };
   };
     
     
-  PRLock *_dd_mutex;
+  Mutex _dd_mutex;
   typedef pdeque<DelayedDatagram> Delayed;
   typedef pdeque<DelayedDatagram> Delayed;
   Delayed _delayed;
   Delayed _delayed;
   bool _delay_active;
   bool _delay_active;

+ 5 - 16
panda/src/net/queuedReturn.I

@@ -16,9 +16,6 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
-#include "config_net.h"
-
-#include <algorithm>
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: QueuedReturn::set_max_queue_size
 //     Function: QueuedReturn::set_max_queue_size
@@ -35,9 +32,8 @@
 template<class Thing>
 template<class Thing>
 void QueuedReturn<Thing>::
 void QueuedReturn<Thing>::
 set_max_queue_size(int max_size) {
 set_max_queue_size(int max_size) {
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   _max_queue_size = max_size;
   _max_queue_size = max_size;
-  PR_Unlock(_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -60,9 +56,8 @@ get_max_queue_size() const {
 template<class Thing>
 template<class Thing>
 int QueuedReturn<Thing>::
 int QueuedReturn<Thing>::
 get_current_queue_size() const {
 get_current_queue_size() const {
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   int size = _things.size();
   int size = _things.size();
-  PR_Unlock(_mutex);
   return size;
   return size;
 }
 }
 
 
@@ -100,7 +95,6 @@ reset_overflow_flag() {
 template<class Thing>
 template<class Thing>
 QueuedReturn<Thing>::
 QueuedReturn<Thing>::
 QueuedReturn() {
 QueuedReturn() {
-  _mutex = PR_NewLock();
   _available = false;
   _available = false;
   _max_queue_size = get_net_max_response_queue();
   _max_queue_size = get_net_max_response_queue();
   _overflow_flag = false;
   _overflow_flag = false;
@@ -114,7 +108,6 @@ QueuedReturn() {
 template<class Thing>
 template<class Thing>
 QueuedReturn<Thing>::
 QueuedReturn<Thing>::
 ~QueuedReturn() {
 ~QueuedReturn() {
-  PR_DestroyLock(_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -145,18 +138,16 @@ thing_available() const {
 template<class Thing>
 template<class Thing>
 bool QueuedReturn<Thing>::
 bool QueuedReturn<Thing>::
 get_thing(Thing &result) {
 get_thing(Thing &result) {
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   if (_things.empty()) {
   if (_things.empty()) {
     // Huh.  Nothing after all.
     // Huh.  Nothing after all.
     _available = false;
     _available = false;
-    PR_Unlock(_mutex);
     return false;
     return false;
   }
   }
 
 
   result = _things.front();
   result = _things.front();
   _things.pop_front();
   _things.pop_front();
   _available = !_things.empty();
   _available = !_things.empty();
-  PR_Unlock(_mutex);
   return true;
   return true;
 }
 }
 
 
@@ -170,7 +161,7 @@ get_thing(Thing &result) {
 template<class Thing>
 template<class Thing>
 bool QueuedReturn<Thing>::
 bool QueuedReturn<Thing>::
 enqueue_thing(const Thing &thing) {
 enqueue_thing(const Thing &thing) {
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   bool enqueue_ok = ((int)_things.size() < _max_queue_size);
   bool enqueue_ok = ((int)_things.size() < _max_queue_size);
   if (enqueue_ok) {
   if (enqueue_ok) {
     _things.push_back(thing);
     _things.push_back(thing);
@@ -178,7 +169,6 @@ enqueue_thing(const Thing &thing) {
     _overflow_flag = true;
     _overflow_flag = true;
   }
   }
   _available = true;
   _available = true;
-  PR_Unlock(_mutex);
 
 
   return enqueue_ok;
   return enqueue_ok;
 }
 }
@@ -195,7 +185,7 @@ enqueue_thing(const Thing &thing) {
 template<class Thing>
 template<class Thing>
 bool QueuedReturn<Thing>::
 bool QueuedReturn<Thing>::
 enqueue_unique_thing(const Thing &thing) {
 enqueue_unique_thing(const Thing &thing) {
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   bool enqueue_ok = ((int)_things.size() < _max_queue_size);
   bool enqueue_ok = ((int)_things.size() < _max_queue_size);
   if (enqueue_ok) {
   if (enqueue_ok) {
     if (find(_things.begin(), _things.end(), thing) == _things.end()) {
     if (find(_things.begin(), _things.end(), thing) == _things.end()) {
@@ -210,7 +200,6 @@ enqueue_unique_thing(const Thing &thing) {
     _overflow_flag = true;
     _overflow_flag = true;
   }
   }
   _available = true;
   _available = true;
-  PR_Unlock(_mutex);
 
 
   return enqueue_ok;
   return enqueue_ok;
 }
 }

+ 6 - 3
panda/src/net/queuedReturn.h

@@ -24,9 +24,12 @@
 #include "connectionListener.h"
 #include "connectionListener.h"
 #include "connection.h"
 #include "connection.h"
 #include "netAddress.h"
 #include "netAddress.h"
-
-#include <prlock.h>
+#include "pmutex.h"
 #include "pdeque.h"
 #include "pdeque.h"
+#include "config_net.h"
+#include "mutexHolder.h"
+
+#include <algorithm>
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : QueuedReturn
 //       Class : QueuedReturn
@@ -56,7 +59,7 @@ protected:
   bool enqueue_unique_thing(const Thing &thing);
   bool enqueue_unique_thing(const Thing &thing);
 
 
 private:
 private:
-  PRLock *_mutex;
+  Mutex _mutex;
   pdeque<Thing> _things;
   pdeque<Thing> _things;
   bool _available;
   bool _available;
   int _max_queue_size;
   int _max_queue_size;

+ 3 - 8
panda/src/net/recentConnectionReader.cxx

@@ -18,6 +18,7 @@
 
 
 #include "recentConnectionReader.h"
 #include "recentConnectionReader.h"
 #include "config_net.h"
 #include "config_net.h"
+#include "mutexHolder.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: RecentConnectionReader::Constructor
 //     Function: RecentConnectionReader::Constructor
@@ -33,7 +34,6 @@ RecentConnectionReader(ConnectionManager *manager) :
   // this should be impossible, because we can't receive datagrams
   // this should be impossible, because we can't receive datagrams
   // before we call add_connection().
   // before we call add_connection().
   _available = false;
   _available = false;
-  _mutex = PR_NewLock();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -46,8 +46,6 @@ RecentConnectionReader::
   // We call shutdown() here to guarantee that all threads are gone
   // We call shutdown() here to guarantee that all threads are gone
   // before the RecentConnectionReader destructs.
   // before the RecentConnectionReader destructs.
   shutdown();
   shutdown();
-
-  PR_DestroyLock(_mutex);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -76,16 +74,14 @@ data_available() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool RecentConnectionReader::
 bool RecentConnectionReader::
 get_data(NetDatagram &result) {
 get_data(NetDatagram &result) {
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   if (!_available) {
   if (!_available) {
     // Huh.  Nothing after all.
     // Huh.  Nothing after all.
-    PR_Unlock(_mutex);
     return false;
     return false;
   }
   }
 
 
   result = _datagram;
   result = _datagram;
   _available = false;
   _available = false;
-  PR_Unlock(_mutex);
   return true;
   return true;
 }
 }
 
 
@@ -125,8 +121,7 @@ receive_datagram(const NetDatagram &datagram) {
       << " bytes\n";
       << " bytes\n";
   }
   }
 
 
-  PR_Lock(_mutex);
+  MutexHolder holder(_mutex);
   _datagram = datagram;
   _datagram = datagram;
   _available = true;
   _available = true;
-  PR_Unlock(_mutex);
 }
 }

+ 2 - 3
panda/src/net/recentConnectionReader.h

@@ -23,8 +23,7 @@
 
 
 #include "connectionReader.h"
 #include "connectionReader.h"
 #include "netDatagram.h"
 #include "netDatagram.h"
-
-#include <prlock.h>
+#include "pmutex.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : RecentConnectionReader
 //       Class : RecentConnectionReader
@@ -53,7 +52,7 @@ protected:
 private:
 private:
   bool _available;
   bool _available;
   Datagram _datagram;
   Datagram _datagram;
-  PRLock *_mutex;
+  Mutex _mutex;
 };
 };
 
 
 #endif
 #endif

+ 2 - 2
panda/src/net/test_raw_server.cxx

@@ -25,7 +25,7 @@
 #include "netAddress.h"
 #include "netAddress.h"
 #include "connection.h"
 #include "connection.h"
 #include "netDatagram.h"
 #include "netDatagram.h"
-
+#include "thread.h"
 #include "pset.h"
 #include "pset.h"
 
 
 int
 int
@@ -99,7 +99,7 @@ main(int argc, char *argv[]) {
     }
     }
 
 
     // Yield the timeslice before we poll again.
     // Yield the timeslice before we poll again.
-    PR_Sleep(PR_MillisecondsToInterval(100));
+    Thread::sleep(0.1);
   }
   }
 
 
   return (0);
   return (0);

+ 10 - 9
panda/src/net/test_spam_client.cxx

@@ -22,10 +22,9 @@
 #include "netAddress.h"
 #include "netAddress.h"
 #include "connection.h"
 #include "connection.h"
 #include "netDatagram.h"
 #include "netDatagram.h"
-
+#include "clockObject.h"
 #include "datagram_ui.h"
 #include "datagram_ui.h"
-
-#include <prinrval.h>
+#include "thread.h"
 
 
 int
 int
 main(int argc, char *argv[]) {
 main(int argc, char *argv[]) {
@@ -69,12 +68,14 @@ main(int argc, char *argv[]) {
 
 
   int num_sent = 0;
   int num_sent = 0;
   int num_received = 0;
   int num_received = 0;
-  PRIntervalTime last_reported_time = PR_IntervalNow();
-  PRIntervalTime report_interval = PR_SecondsToInterval(5);
+
+  ClockObject *global_clock = ClockObject::get_global_clock();
+  double last_reported_time = global_clock->get_real_time();
+  static const double report_interval = 5.0;
 
 
   while (!lost_connection) {
   while (!lost_connection) {
     // Send the datagram.
     // Send the datagram.
-    if (writer.send(datagram, c, host)) {
+    if (writer.send(datagram, c)) {
       num_sent++;
       num_sent++;
     }
     }
 
 
@@ -99,15 +100,15 @@ main(int argc, char *argv[]) {
       }
       }
     }
     }
 
 
-    PRIntervalTime now = PR_IntervalNow();
-    if ((PRIntervalTime)(now - last_reported_time) > report_interval) {
+    double now = global_clock->get_real_time();
+    if ((now - last_reported_time) > report_interval) {
       nout << "Sent " << num_sent << ", received "
       nout << "Sent " << num_sent << ", received "
            << num_received << " datagrams.\n";
            << num_received << " datagrams.\n";
       last_reported_time = now;
       last_reported_time = now;
     }
     }
 
 
     // Yield the timeslice before we poll again.
     // Yield the timeslice before we poll again.
-    //    PR_Sleep(PR_MillisecondsToInterval(1));
+    Thread::sleep(0.001);
   }
   }
 
 
   return (0);
   return (0);

+ 9 - 7
panda/src/net/test_spam_server.cxx

@@ -27,8 +27,8 @@
 #include "netDatagram.h"
 #include "netDatagram.h"
 
 
 #include "datagram_ui.h"
 #include "datagram_ui.h"
-
-#include <prinrval.h>
+#include "clockObject.h"
+#include "thread.h"
 
 
 #include "pset.h"
 #include "pset.h"
 #include <sys/time.h>
 #include <sys/time.h>
@@ -65,8 +65,10 @@ main(int argc, char *argv[]) {
 
 
   int num_sent = 0;
   int num_sent = 0;
   int num_received = 0;
   int num_received = 0;
-  PRIntervalTime last_reported_time = PR_IntervalNow();
-  PRIntervalTime report_interval = PR_SecondsToInterval(5);
+
+  ClockObject *global_clock = ClockObject::get_global_clock();
+  double last_reported_time = global_clock->get_real_time();
+  static const double report_interval = 5.0;
 
 
   bool shutdown = false;
   bool shutdown = false;
   while (!shutdown) {
   while (!shutdown) {
@@ -107,15 +109,15 @@ main(int argc, char *argv[]) {
       }
       }
     }
     }
 
 
-    PRIntervalTime now = PR_IntervalNow();
-    if ((PRIntervalTime)(now - last_reported_time) > report_interval) {
+    double now = global_clock->get_real_time();
+    if ((now - last_reported_time) > report_interval) {
       nout << "Sent " << num_sent << ", received "
       nout << "Sent " << num_sent << ", received "
            << num_received << " datagrams.\n";
            << num_received << " datagrams.\n";
       last_reported_time = now;
       last_reported_time = now;
     }
     }
 
 
     // Yield the timeslice before we poll again.
     // Yield the timeslice before we poll again.
-    //    PR_Sleep(PR_MillisecondsToInterval(1));
+    Thread::sleep(0.001);
   }
   }
 
 
   return (0);
   return (0);

+ 2 - 2
panda/src/net/test_tcp_server.cxx

@@ -25,7 +25,7 @@
 #include "netAddress.h"
 #include "netAddress.h"
 #include "connection.h"
 #include "connection.h"
 #include "netDatagram.h"
 #include "netDatagram.h"
-
+#include "thread.h"
 #include "datagram_ui.h"
 #include "datagram_ui.h"
 
 
 #include "pset.h"
 #include "pset.h"
@@ -119,7 +119,7 @@ main(int argc, char *argv[]) {
     }
     }
 
 
     // Yield the timeslice before we poll again.
     // Yield the timeslice before we poll again.
-    PR_Sleep(PR_MillisecondsToInterval(100));
+    Thread::sleep(0.1);
   }
   }
 
 
   return (0);
   return (0);

+ 1 - 0
panda/src/pipeline/Sources.pp

@@ -6,6 +6,7 @@
 
 
 #begin lib_target
 #begin lib_target
   #define TARGET pipeline
   #define TARGET pipeline
+  #define USE_PACKAGES threads
   
   
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
 
 

+ 6 - 1
panda/src/pstatclient/pStatClientImpl.cxx

@@ -458,9 +458,14 @@ handle_server_control_message(const PStatServerControlMessage &message) {
 //               has been lost.
 //               has been lost.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void PStatClientImpl::
 void PStatClientImpl::
-connection_reset(const PT(Connection) &connection, PRErrorCode) {
+connection_reset(const PT(Connection) &connection, bool) {
   if (connection == _tcp_connection) {
   if (connection == _tcp_connection) {
     _client->client_disconnect();
     _client->client_disconnect();
+  } else if (connection == _udp_connection) {
+    pstats_cat.warning()
+      << "Trouble sending UDP; switching to TCP only.\n";
+    _tcp_count_factor = 0.0f;
+    _udp_count_factor = 1.0f;
   } else {
   } else {
     pstats_cat.warning()
     pstats_cat.warning()
       << "Ignoring spurious connection_reset() message\n";
       << "Ignoring spurious connection_reset() message\n";

+ 1 - 1
panda/src/pstatclient/pStatClientImpl.h

@@ -94,7 +94,7 @@ private:
   void handle_server_control_message(const PStatServerControlMessage &message);
   void handle_server_control_message(const PStatServerControlMessage &message);
 
 
   virtual void connection_reset(const PT(Connection) &connection, 
   virtual void connection_reset(const PT(Connection) &connection, 
-                                PRErrorCode errcode);
+                                bool okflag);
 
 
   PStatClient *_client;
   PStatClient *_client;
 
 

+ 3 - 6
pandatool/src/pstatserver/pStatServer.cxx

@@ -18,7 +18,7 @@
 
 
 #include "pStatServer.h"
 #include "pStatServer.h"
 #include "pStatReader.h"
 #include "pStatReader.h"
-
+#include "thread.h"
 #include "config_pstats.h"
 #include "config_pstats.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -146,10 +146,7 @@ void PStatServer::
 main_loop(bool *interrupt_flag) {
 main_loop(bool *interrupt_flag) {
   while (interrupt_flag == (bool *)NULL || !*interrupt_flag) {
   while (interrupt_flag == (bool *)NULL || !*interrupt_flag) {
     poll();
     poll();
-    // Not great.  This will totally blow in a threaded environment.
-    // We need a portable way to sleep or block.
-    PRIntervalTime sleep_timeout = PR_MillisecondsToInterval(100);
-    PR_Sleep(sleep_timeout);
+    Thread::sleep(0.1);
   }
   }
 }
 }
 
 
@@ -336,7 +333,7 @@ is_thread_safe() {
 //               parties and clean up gracefully.
 //               parties and clean up gracefully.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void PStatServer::
 void PStatServer::
-connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
+connection_reset(const PT(Connection) &connection, bool okflag) {
   // Was this a client connection?  Tell the reader about it if it
   // Was this a client connection?  Tell the reader about it if it
   // was.
   // was.
   close_connection(connection);
   close_connection(connection);

+ 1 - 1
pandatool/src/pstatserver/pStatServer.h

@@ -70,7 +70,7 @@ public:
 
 
 protected:
 protected:
   virtual void connection_reset(const PT(Connection) &connection, 
   virtual void connection_reset(const PT(Connection) &connection, 
-                                PRErrorCode errcode);
+                                bool okflag);
 
 
 private:
 private:
   void user_guide_bars_changed();
   void user_guide_bars_changed();