completely shoot nspr
This commit is contained in:
parent
ce36e31e6a
commit
baa0f8039c
|
|
@ -162,9 +162,6 @@
|
|||
#define PYTHON_IPATH /usr/local/include/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_097 1
|
||||
|
||||
|
|
@ -190,4 +187,3 @@
|
|||
//#defer alt_ipath $[alt_ipath] /usr/local/include
|
||||
//#defer alt_lpath $[alt_lpath] /usr/local/lib
|
||||
|
||||
#defer NSPR_LIBS $[NSPR_LIBS] thr
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
// *******************************************************************
|
||||
|
||||
// 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=
|
||||
|
||||
// Additional flags to pass to the Tau instrumentor.
|
||||
|
|
|
|||
|
|
@ -398,22 +398,17 @@
|
|||
//#defer ALTERNATIVE_MALLOC $[or $[WINDOWS_PLATFORM],$[DO_MEMORY_USAGE],$[not $[HAVE_THREADS]]]
|
||||
#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 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
|
||||
// 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
|
||||
// available (most people will have one). Windows has one built-in.
|
||||
// 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 THREADS_LIBS $[if $[not $[WINDOWS_PLATFORM]],pthread]
|
||||
|
||||
// Whether threading is defined or not, you might want to validate the
|
||||
// thread and synchronization operations. With threading enabled,
|
||||
|
|
@ -703,17 +697,6 @@
|
|||
// than CPU's. Even then, OS-based locking is probably better.
|
||||
#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
|
||||
// performance statistics? This requires NET to be available. By
|
||||
// default, we don't build PStats when OPTIMIZE = 4, although this is
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@
|
|||
|
||||
#print
|
||||
#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]
|
||||
#print + OpenSSL
|
||||
#else
|
||||
|
|
@ -181,9 +176,6 @@ $[cdefine MAYA_PRE_5_0]
|
|||
/* Define if we have SoftImage available. */
|
||||
$[cdefine HAVE_SOFTIMAGE]
|
||||
|
||||
/* Define if we have NSPR installed. */
|
||||
$[cdefine HAVE_NSPR]
|
||||
|
||||
/* Define if we have OpenSSL installed. */
|
||||
$[cdefine HAVE_OPENSSL]
|
||||
$[cdefine OPENSSL_097]
|
||||
|
|
|
|||
|
|
@ -108,10 +108,12 @@
|
|||
#set PYTHON_FRAMEWORK $[unixfilename $[PYTHON_FRAMEWORK]]
|
||||
#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_LPATH $[unixfilename $[OPENSSL_LPATH]]
|
||||
|
|
@ -238,11 +240,6 @@
|
|||
#set DEBUG_THREADS $[DEBUG_THREADS]
|
||||
#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 RAD_MSS_IPATH $[unixfilename $[RAD_MSS_IPATH]]
|
||||
|
|
|
|||
|
|
@ -97,12 +97,12 @@
|
|||
#define python_framework $[PYTHON_FRAMEWORK]
|
||||
#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
|
||||
|
||||
#if $[HAVE_OPENSSL]
|
||||
|
|
@ -458,8 +458,8 @@
|
|||
// on the various external packages this particular target claims to
|
||||
// require.
|
||||
#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]
|
||||
#set alt_cflags $[alt_cflags] $[$[package]_cflags]
|
||||
|
|
@ -472,8 +472,8 @@
|
|||
// on the various external packages this particular target claims to
|
||||
// require.
|
||||
#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]
|
||||
#set alt_lflags $[alt_lflags] $[$[package]_lflags]
|
||||
|
|
@ -487,8 +487,8 @@
|
|||
// claims to require. This returns a space-separated set of directory
|
||||
// names only; the -I switch is not included here.
|
||||
#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]
|
||||
#set alt_ipath $[alt_ipath] $[$[package]_ipath]
|
||||
|
|
@ -502,7 +502,7 @@
|
|||
// target claims to require. This returns a space-separated set of
|
||||
// directory names only; the -L switch is not included here.
|
||||
#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]
|
||||
#set alt_lpath $[WIN32_PLATFORMSDK_LIBPATH] $[alt_lpath]
|
||||
|
|
@ -520,7 +520,7 @@
|
|||
// target claims to require. This returns a space-separated set of
|
||||
// directory names only; the -F switch is not included here.
|
||||
#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]
|
||||
#set alt_fpath $[alt_fpath] $[$[package]_fpath]
|
||||
|
|
@ -534,7 +534,7 @@
|
|||
// target claims to require. This returns a space-separated set of
|
||||
// framework names only; the -framework switch is not included here.
|
||||
#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]
|
||||
#set alt_frameworks $[alt_frameworks] $[OSX_SYS_FRAMEWORKS]
|
||||
|
|
@ -553,7 +553,7 @@
|
|||
// space-separated set of library names only; the -l switch is not
|
||||
// included here.
|
||||
#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]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#define SELECT_TAU select.tau
|
||||
#define USE_PACKAGES threads
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET dtoolbase
|
||||
|
|
@ -10,7 +11,6 @@
|
|||
atomicAdjust.h \
|
||||
atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
|
||||
atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
|
||||
atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \
|
||||
atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
|
||||
atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
|
||||
cmath.I cmath.h \
|
||||
|
|
@ -22,7 +22,6 @@
|
|||
memoryBase.h \
|
||||
mutexImpl.h \
|
||||
mutexDummyImpl.h mutexDummyImpl.I \
|
||||
mutexNsprImpl.h mutexNsprImpl.I \
|
||||
mutexLinuxImpl.h mutexLinuxImpl.I \
|
||||
mutexPosixImpl.h mutexPosixImpl.I \
|
||||
mutexWin32Impl.h mutexWin32Impl.I \
|
||||
|
|
@ -44,13 +43,11 @@
|
|||
addHash.cxx \
|
||||
atomicAdjustDummyImpl.cxx \
|
||||
atomicAdjustI386Impl.cxx \
|
||||
atomicAdjustNsprImpl.cxx \
|
||||
atomicAdjustPosixImpl.cxx \
|
||||
atomicAdjustWin32Impl.cxx \
|
||||
dtoolbase.cxx \
|
||||
memoryBase.cxx \
|
||||
mutexDummyImpl.cxx \
|
||||
mutexNsprImpl.cxx \
|
||||
mutexLinuxImpl.cxx \
|
||||
mutexPosixImpl.cxx \
|
||||
mutexWin32Impl.cxx \
|
||||
|
|
@ -65,7 +62,6 @@
|
|||
atomicAdjust.h \
|
||||
atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I \
|
||||
atomicAdjustI386Impl.h atomicAdjustI386Impl.I \
|
||||
atomicAdjustNsprImpl.h atomicAdjustNsprImpl.I \
|
||||
atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I \
|
||||
atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I \
|
||||
cmath.I cmath.h \
|
||||
|
|
@ -76,7 +72,6 @@
|
|||
memoryBase.h \
|
||||
mutexImpl.h \
|
||||
mutexDummyImpl.h mutexDummyImpl.I \
|
||||
mutexNsprImpl.h mutexNsprImpl.I \
|
||||
mutexLinuxImpl.h mutexLinuxImpl.I \
|
||||
mutexPosixImpl.h mutexPosixImpl.I \
|
||||
mutexWin32Impl.h mutexWin32Impl.I \
|
||||
|
|
|
|||
|
|
@ -60,11 +60,6 @@ typedef AtomicAdjustWin32Impl AtomicAdjust;
|
|||
#include "atomicAdjustPosixImpl.h"
|
||||
typedef AtomicAdjustPosixImpl AtomicAdjust;
|
||||
|
||||
#elif defined(THREAD_NSPR_IMPL)
|
||||
|
||||
#include "atomicAdjustNsprImpl.h"
|
||||
typedef AtomicAdjustNsprImpl AtomicAdjust;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#include "addHash.cxx"
|
||||
#include "atomicAdjustDummyImpl.cxx"
|
||||
#include "atomicAdjustI386Impl.cxx"
|
||||
#include "atomicAdjustNsprImpl.cxx"
|
||||
#include "atomicAdjustPosixImpl.cxx"
|
||||
#include "atomicAdjustWin32Impl.cxx"
|
||||
#include "dtoolbase.cxx"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "mutexDummyImpl.cxx"
|
||||
#include "mutexNsprImpl.cxx"
|
||||
#include "mutexLinuxImpl.cxx"
|
||||
#include "mutexPosixImpl.cxx"
|
||||
#include "mutexWin32Impl.cxx"
|
||||
|
|
|
|||
|
|
@ -55,13 +55,6 @@ typedef MutexPosixImpl MutexImpl;
|
|||
typedef ReMutexPosixImpl ReMutexImpl;
|
||||
#define HAVE_REMUTEXIMPL 1
|
||||
|
||||
#elif defined(THREAD_NSPR_IMPL)
|
||||
|
||||
#include "mutexNsprImpl.h"
|
||||
typedef MutexNsprImpl MutexImpl;
|
||||
typedef ReMutexNsprImpl ReMutexImpl;
|
||||
#define HAVE_REMUTEXIMPL 1
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
}
|
||||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
|
|
@ -25,34 +25,7 @@
|
|||
// the various numeric types for unsigned and signed numbers of
|
||||
// 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 short PN_int16;
|
||||
|
|
@ -73,8 +46,6 @@ typedef unsigned long long PN_uint64;
|
|||
typedef double PN_float64;
|
||||
typedef float PN_float32;
|
||||
|
||||
#endif // HAVE_NSPR
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,6 @@
|
|||
// Posix threads are nice.
|
||||
#define THREAD_POSIX_IMPL 1
|
||||
|
||||
#elif defined(HAVE_NSPR)
|
||||
|
||||
// If NSPR is available, use that.
|
||||
#define THREAD_NSPR_IMPL 1
|
||||
|
||||
#else
|
||||
|
||||
// This is a configuration error. For some reason, HAVE_THREADS is
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
pair pthread.h queue set stack stdcompare.h stdtypedefs.h \
|
||||
string vector windows.h winsock2.h zlib.h files.h hex.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 \
|
||||
hxcomm.h hxcore.h hxengin.h hxerror.h hxfiles.h hxtbuf.h \
|
||||
hxtbuff.h hxwin.h Python.h Cg/cg.h Cg/cgGL.h \
|
||||
|
|
|
|||
|
|
@ -9,5 +9,6 @@ struct EVP_PKEY;
|
|||
struct X509;
|
||||
struct X509_STORE;
|
||||
struct X509_NAME;
|
||||
struct SSL;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#begin lib_target
|
||||
#define TARGET express
|
||||
#define USE_PACKAGES nspr net zlib openssl
|
||||
#define USE_PACKAGES zlib openssl
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
dtoolutil:c dtoolbase:c prc:c dtool:m
|
||||
|
||||
#define BUILD_DIRECTORY $[WANT_NATIVE_NET]
|
||||
#define USE_PACKAGES native_net
|
||||
#define USE_PACKAGES native_net openssl
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET nativenet
|
||||
|
|
@ -19,12 +19,22 @@
|
|||
socket_tcp_listen.h time_accumulator.h time_out.h \
|
||||
socket_address.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 \
|
||||
socket_udp_outgoing.h time_general.h
|
||||
|
||||
|
||||
#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 \
|
||||
buffered_datagramconnection.h \
|
||||
|
|
@ -33,7 +43,9 @@
|
|||
buffered_datagramreader.h buffered_datagramreader.i \
|
||||
socket_address.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 \
|
||||
socket_udp_outgoing.h time_general.h
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "buffered_datagramconnection.h"
|
||||
|
||||
TypeHandle Buffered_DatagramConnection::_type_handle;
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
// 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:
|
||||
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_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
|
||||
// Description : used to do a full reset of buffers
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
#include "numeric_types.h"
|
||||
#include "socket_portable.h"
|
||||
|
||||
///////////////////////////////////
|
||||
// Class : Socket_Address
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "pandabase.h"
|
||||
#include "numeric_types.h"
|
||||
#include "time_base.h"
|
||||
#include "socket_ip.h"
|
||||
|
||||
class Socket_fdset
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef __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...
|
||||
class Socket_TCP;
|
||||
class Socket_UDP;
|
||||
|
|
@ -26,8 +31,7 @@ class Socket_UDP_Outgoing;
|
|||
// socket_fdset
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Socket_IP
|
||||
{
|
||||
class EXPCL_PANDA Socket_IP : public TypedObject {
|
||||
public:
|
||||
PUBLISHED:
|
||||
|
||||
|
|
@ -39,7 +43,7 @@ PUBLISHED:
|
|||
inline static int GetLastError();
|
||||
inline int SetNonBlocking();
|
||||
inline int SetBlocking();
|
||||
inline bool SetReuseAddress();
|
||||
inline bool SetReuseAddress(bool flag = true);
|
||||
inline bool Active();
|
||||
inline int SetRecvBufferSize(int size);
|
||||
inline void SetSocket(SOCKET ins);
|
||||
|
|
@ -62,6 +66,23 @@ private:
|
|||
friend class Socket_UDP_Incoming;
|
||||
friend class Socket_UDP_Outgoing;
|
||||
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
|
||||
// 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)
|
||||
return false;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef __SOCKET_TCP_H__
|
||||
#define __SOCKET_TCP_H__
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "socket_ip.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_TCP
|
||||
//
|
||||
|
|
@ -15,7 +18,7 @@ public:
|
|||
PUBLISHED:
|
||||
inline Socket_TCP(SOCKET);
|
||||
inline Socket_TCP() { };
|
||||
inline int SetNoDelay();
|
||||
inline int SetNoDelay(bool flag = true);
|
||||
inline int SetLinger(int interval_seconds = 0);
|
||||
inline int DontLinger();
|
||||
inline int SetSendBufferSize(int insize);
|
||||
|
|
@ -30,6 +33,23 @@ PUBLISHED:
|
|||
public:
|
||||
inline int SendData(const 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
|
||||
// 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;
|
||||
ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "socket_tcp_listen.h"
|
||||
|
||||
TypeHandle Socket_TCP_Listen::_type_handle;
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef __SOCKET_TCP_LISTEN_H__
|
||||
#define __SOCKET_TCP_LISTEN_H__
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "socket_ip.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Class : Socket_TCP_Listen
|
||||
// Description : Base functionality for a TCP rendezvous socket
|
||||
|
|
@ -11,29 +14,48 @@ public:
|
|||
PUBLISHED:
|
||||
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);
|
||||
public:
|
||||
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
|
||||
// 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();
|
||||
_socket = DO_NEWTCP();
|
||||
|
||||
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;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1,17 +1,12 @@
|
|||
#ifndef __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 "socket_ip.h"
|
||||
#include "numeric_types.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <openssl/rsa.h> /* SSLeay stuff */
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
|
|
@ -19,9 +14,14 @@
|
|||
#include <openssl/ssl.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
|
||||
|
|
@ -47,7 +47,7 @@ struct SSlStartup
|
|||
};
|
||||
|
||||
|
||||
class Socket_TCP_SSL : public Socket_IP
|
||||
class EXPCL_PANDA Socket_TCP_SSL : public Socket_IP
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
@ -84,6 +84,23 @@ private:
|
|||
_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;
|
||||
SSL_set_fd (_ssl,(int)GetSocket() );
|
||||
|
||||
int err = SSL_accept(_ssl);
|
||||
SSL_accept(_ssl);
|
||||
ERR_clear_error();
|
||||
|
||||
// printf(" Ssl Accept = %d \n",err);
|
||||
|
|
@ -244,7 +261,9 @@ inline bool Socket_TCP_SSL::ErrorIs_WouldBlocking(int err)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -296,9 +315,13 @@ inline void Socket_TCP_SSL::DetailErrorFormat(void)
|
|||
{
|
||||
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");
|
||||
LOGWARNING("Socket_TCP_SSL::DetailErrorFormat->[%s]",buf2);
|
||||
nativenet_cat.warning()
|
||||
<< "Socket_TCP_SSL::DetailErrorFormat->[" << buf2 << "]\n";
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#endif //__SOCKET_TCP_SSL_H__
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "socket_udp.h"
|
||||
|
||||
TypeHandle Socket_UDP::_type_handle;
|
||||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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__
|
||||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "socket_udp_incoming.h"
|
||||
|
||||
TypeHandle Socket_UDP_Incoming::_type_handle;
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
#ifndef __SOCKET_UDP_INCOMING_H__
|
||||
#define __SOCKET_UDP_INCOMING_H__
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "socket_ip.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// 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:
|
||||
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 SendTo(const char * data, int len, const Socket_Address & address);
|
||||
inline bool InitNoAddress();
|
||||
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
|
||||
// Description : Flips the OS bits that allow for brodcast
|
||||
|
|
@ -57,7 +80,7 @@ inline bool Socket_UDP_Incoming::InitNoAddress()
|
|||
// Return type : bool
|
||||
// Argument : NetAddress & address
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Incoming::OpenForInput(Socket_Address & address)
|
||||
inline bool Socket_UDP_Incoming::OpenForInput(const Socket_Address & address)
|
||||
{
|
||||
Close();
|
||||
_socket = DO_NEWUDP();
|
||||
|
|
@ -77,7 +100,7 @@ inline bool Socket_UDP_Incoming::OpenForInput(Socket_Address & address)
|
|||
// Return type : bool
|
||||
// Argument : NetAddress & address
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool Socket_UDP_Incoming::OpenForInputMCast(Socket_Address & address)
|
||||
inline bool Socket_UDP_Incoming::OpenForInputMCast(const Socket_Address & address)
|
||||
{
|
||||
Close();
|
||||
_socket = DO_NEWUDP();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "socket_udp_outgoing.h"
|
||||
|
||||
TypeHandle Socket_UDP_Outgoing::_type_handle;
|
||||
|
|
@ -15,7 +15,7 @@ PUBLISHED:
|
|||
inline Socket_UDP_Outgoing() { }
|
||||
|
||||
// use this interface for a tagreted UDP connection
|
||||
inline bool InitToAddress(Socket_Address & address);
|
||||
inline bool InitToAddress(const Socket_Address & address);
|
||||
public:
|
||||
inline bool Send(const char * data, int len);
|
||||
PUBLISHED:
|
||||
|
|
@ -27,6 +27,23 @@ public:
|
|||
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_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
|
||||
|
|
@ -49,7 +66,7 @@ inline bool Socket_UDP_Outgoing::SetToBroadCast()
|
|||
// Return type : inline bool
|
||||
// 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)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#define OTHER_LIBS \
|
||||
interrogatedb:c dconfig:c dtoolconfig: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
|
||||
#define TARGET net
|
||||
#define LOCAL_LIBS \
|
||||
express pandabase
|
||||
express pandabase nativenet pipeline
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
datagramTCPHeader.I datagramTCPHeader.h \
|
||||
datagramUDPHeader.I datagramUDPHeader.h \
|
||||
netAddress.h netDatagram.I netDatagram.h \
|
||||
pprerror.h queuedConnectionListener.I \
|
||||
queuedConnectionListener.I \
|
||||
queuedConnectionListener.h queuedConnectionManager.h \
|
||||
queuedConnectionReader.h recentConnectionReader.h \
|
||||
queuedReturn.h queuedReturn.I
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
connectionManager.cxx connectionReader.cxx \
|
||||
connectionWriter.cxx datagramQueue.cxx datagramTCPHeader.cxx \
|
||||
datagramUDPHeader.cxx netAddress.cxx netDatagram.cxx \
|
||||
pprerror.cxx queuedConnectionListener.cxx \
|
||||
queuedConnectionListener.cxx \
|
||||
queuedConnectionManager.cxx queuedConnectionReader.cxx \
|
||||
recentConnectionReader.cxx
|
||||
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
datagramTCPHeader.I datagramTCPHeader.h \
|
||||
datagramUDPHeader.I datagramUDPHeader.h \
|
||||
netAddress.h netDatagram.I \
|
||||
netDatagram.h pprerror.h queuedConnectionListener.I \
|
||||
netDatagram.h queuedConnectionListener.I \
|
||||
queuedConnectionListener.h queuedConnectionManager.h \
|
||||
queuedConnectionReader.h queuedReturn.I queuedReturn.h \
|
||||
recentConnectionReader.h
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_spam_client
|
||||
#define LOCAL_LIBS net
|
||||
#define LOCAL_LIBS net putil
|
||||
#define OTHER_LIBS $[OTHER_LIBS] pystub
|
||||
|
||||
#define SOURCES \
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_spam_server
|
||||
#define LOCAL_LIBS net
|
||||
#define LOCAL_LIBS net putil
|
||||
#define OTHER_LIBS $[OTHER_LIBS] pystub
|
||||
|
||||
#define SOURCES \
|
||||
|
|
|
|||
|
|
@ -21,11 +21,15 @@
|
|||
#include "netDatagram.h"
|
||||
#include "datagramTCPHeader.h"
|
||||
#include "datagramUDPHeader.h"
|
||||
#include "pprerror.h"
|
||||
#include "config_net.h"
|
||||
#include "config_express.h" // for collect_tcp
|
||||
#include "trueClock.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(ConnectionManager *manager, PRFileDesc *socket) :
|
||||
Connection(ConnectionManager *manager, Socket_IP *socket) :
|
||||
_manager(manager),
|
||||
_socket(socket)
|
||||
{
|
||||
_write_mutex = PR_NewLock();
|
||||
_collect_tcp = collect_tcp;
|
||||
_collect_tcp_interval = collect_tcp_interval;
|
||||
_queued_data_start = 0.0;
|
||||
|
|
@ -58,16 +61,12 @@ Connection::
|
|||
net_cat.info()
|
||||
<< "Deleting connection " << (void *)this << "\n";
|
||||
|
||||
if (_socket != (PRFileDesc *)NULL) {
|
||||
if (_socket != (Socket_IP *)NULL) {
|
||||
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::
|
||||
get_address() const {
|
||||
PRNetAddr addr;
|
||||
if (PR_GetSockName(_socket, &addr) != PR_SUCCESS) {
|
||||
pprerror("PR_GetSockName");
|
||||
}
|
||||
|
||||
Socket_Address addr = _socket->GetPeerName();
|
||||
return NetAddress(addr);
|
||||
}
|
||||
|
||||
|
|
@ -100,10 +95,10 @@ get_manager() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Connection::get_socket
|
||||
// Access: Published
|
||||
// Description: Returns the internal NSPR pointer that defines the
|
||||
// Description: Returns the internal Socket_IP that defines the
|
||||
// connection.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PRFileDesc *Connection::
|
||||
Socket_IP *Connection::
|
||||
get_socket() const {
|
||||
return _socket;
|
||||
}
|
||||
|
|
@ -182,7 +177,7 @@ get_collect_tcp_interval() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Connection::
|
||||
consider_flush() {
|
||||
PR_Lock(_write_mutex);
|
||||
MutexHolder holder(_write_mutex);
|
||||
|
||||
if (!_collect_tcp) {
|
||||
return do_flush();
|
||||
|
|
@ -197,7 +192,6 @@ consider_flush() {
|
|||
}
|
||||
}
|
||||
|
||||
PR_Unlock(_write_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +204,7 @@ consider_flush() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Connection::
|
||||
flush() {
|
||||
PR_Lock(_write_mutex);
|
||||
MutexHolder holder(_write_mutex);
|
||||
return do_flush();
|
||||
}
|
||||
|
||||
|
|
@ -221,10 +215,11 @@ flush() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Connection::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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.
|
||||
PR_Lock(_write_mutex);
|
||||
Socket_UDP *udp;
|
||||
DCAST_INTO_R(udp, _socket, false);
|
||||
|
||||
MutexHolder holder(_write_mutex);
|
||||
DatagramUDPHeader header(datagram);
|
||||
string data;
|
||||
data += header.get_header();
|
||||
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()) {
|
||||
header.verify_datagram(datagram);
|
||||
}
|
||||
|
||||
|
||||
if (net_cat.is_spam()) {
|
||||
net_cat.spam()
|
||||
<< "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.
|
||||
|
|
@ -409,7 +386,7 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
|
|||
|
||||
DatagramTCPHeader header(datagram, tcp_header_size);
|
||||
|
||||
PR_Lock(_write_mutex);
|
||||
MutexHolder holder(_write_mutex);
|
||||
_queued_data += header.get_header();
|
||||
_queued_data += datagram.get_message();
|
||||
_queued_count++;
|
||||
|
|
@ -423,7 +400,6 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
|
|||
return do_flush();
|
||||
}
|
||||
|
||||
PR_Unlock(_write_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -436,36 +412,30 @@ send_datagram(const NetDatagram &datagram, int tcp_header_size) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Connection::
|
||||
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.
|
||||
Socket_UDP *udp;
|
||||
DCAST_INTO_R(udp, _socket, false);
|
||||
|
||||
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()) {
|
||||
net_cat.spam()
|
||||
<< "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.
|
||||
|
||||
PR_Lock(_write_mutex);
|
||||
MutexHolder holder(_write_mutex);
|
||||
_queued_data += datagram.get_message();
|
||||
_queued_count++;
|
||||
|
||||
|
|
@ -474,7 +444,6 @@ send_raw_datagram(const NetDatagram &datagram) {
|
|||
return do_flush();
|
||||
}
|
||||
|
||||
PR_Unlock(_write_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -482,70 +451,48 @@ send_raw_datagram(const NetDatagram &datagram) {
|
|||
// Function: Connection::do_flush
|
||||
// Access: Private
|
||||
// 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::
|
||||
do_flush() {
|
||||
PRInt32 bytes_to_send = _queued_data.length();
|
||||
if (bytes_to_send == 0) {
|
||||
if (_queued_data.empty()) {
|
||||
_queued_count = 0;
|
||||
_queued_data_start = TrueClock::get_global_ptr()->get_short_time();
|
||||
PR_Unlock(_write_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (net_cat.is_spam()) {
|
||||
net_cat.spam()
|
||||
<< "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_count = 0;
|
||||
_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
|
||||
// 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,9 @@
|
|||
#include "pandabase.h"
|
||||
#include "referenceCount.h"
|
||||
#include "netAddress.h"
|
||||
#include "pmutex.h"
|
||||
|
||||
#include <prio.h>
|
||||
#include <prlock.h>
|
||||
#include <prerror.h>
|
||||
|
||||
class Socket_IP;
|
||||
class ConnectionManager;
|
||||
class NetDatagram;
|
||||
|
||||
|
|
@ -37,13 +35,13 @@ class NetDatagram;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA Connection : public ReferenceCount {
|
||||
PUBLISHED:
|
||||
Connection(ConnectionManager *manager, PRFileDesc *socket);
|
||||
Connection(ConnectionManager *manager, Socket_IP *socket);
|
||||
~Connection();
|
||||
|
||||
NetAddress get_address() const;
|
||||
ConnectionManager *get_manager() const;
|
||||
|
||||
PRFileDesc *get_socket() const;
|
||||
Socket_IP *get_socket() const;
|
||||
|
||||
void set_collect_tcp(bool collect_tcp);
|
||||
bool get_collect_tcp() const;
|
||||
|
|
@ -69,11 +67,11 @@ private:
|
|||
bool send_datagram(const NetDatagram &datagram, int tcp_header_size);
|
||||
bool send_raw_datagram(const NetDatagram &datagram);
|
||||
bool do_flush();
|
||||
bool check_send_error(PRInt32 result, PRErrorCode errcode, PRInt32 bytes_to_send);
|
||||
bool check_send_error(bool okflag);
|
||||
|
||||
ConnectionManager *_manager;
|
||||
PRFileDesc *_socket;
|
||||
PRLock *_write_mutex;
|
||||
Socket_IP *_socket;
|
||||
Mutex _write_mutex;
|
||||
|
||||
bool _collect_tcp;
|
||||
double _collect_tcp_interval;
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
#include "connection.h"
|
||||
#include "connectionManager.h"
|
||||
#include "netAddress.h"
|
||||
#include "pprerror.h"
|
||||
#include "config_net.h"
|
||||
#include "socket_tcp_listen.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionListener::Constructor
|
||||
|
|
@ -56,13 +56,15 @@ receive_datagram(const NetDatagram &) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionListener::
|
||||
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 {
|
||||
NetAddress net_addr(addr);
|
||||
|
|
@ -71,7 +73,7 @@ process_incoming_data(SocketInfo *sinfo) {
|
|||
<< " on port " << sinfo->_connection->get_address().get_port()
|
||||
<< "\n";
|
||||
|
||||
PT(Connection) new_connection = new Connection(_manager, socket);
|
||||
PT(Connection) new_connection = new Connection(_manager, session);
|
||||
if (_manager != (ConnectionManager *)NULL) {
|
||||
_manager->new_connection(new_connection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,8 @@
|
|||
#include "connectionReader.h"
|
||||
#include "connectionWriter.h"
|
||||
#include "netAddress.h"
|
||||
#include "pprerror.h"
|
||||
#include "config_net.h"
|
||||
|
||||
#include <prerror.h>
|
||||
#include "mutexHolder.h"
|
||||
|
||||
#ifdef WIN32_VC
|
||||
#include <winsock.h> // For gethostname()
|
||||
|
|
@ -37,7 +35,6 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
ConnectionManager::
|
||||
ConnectionManager() {
|
||||
_set_mutex = PR_NewLock();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -56,8 +53,6 @@ ConnectionManager::
|
|||
for (wi = _writers.begin(); wi != _writers.end(); ++wi) {
|
||||
(*wi)->clear_manager();
|
||||
}
|
||||
|
||||
PR_DestroyLock(_set_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -65,41 +60,42 @@ ConnectionManager::
|
|||
// Function: ConnectionManager::open_UDP_connection
|
||||
// Access: Public
|
||||
// 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
|
||||
// the actual communication.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Connection) ConnectionManager::
|
||||
open_UDP_connection(int port) {
|
||||
NetAddress address;
|
||||
address.set_any(port);
|
||||
Socket_UDP *socket = new Socket_UDP;
|
||||
|
||||
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);
|
||||
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)();
|
||||
}
|
||||
|
||||
net_cat.info()
|
||||
<< "Creating UDP connection for port " << port << "\n";
|
||||
|
||||
} else {
|
||||
if (!socket->InitNoAddress()) {
|
||||
net_cat.error()
|
||||
<< "Unable to initialize outgoing UDP.\n";
|
||||
delete socket;
|
||||
return PT(Connection)();
|
||||
}
|
||||
|
||||
net_cat.info()
|
||||
<< "Creating UDP connection\n";
|
||||
<< "Creating outgoing UDP connection\n";
|
||||
}
|
||||
|
||||
PT(Connection) connection = new Connection(this, socket);
|
||||
|
|
@ -125,27 +121,12 @@ open_TCP_server_rendezvous(int port, int backlog) {
|
|||
NetAddress address;
|
||||
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()
|
||||
<< "Unable to listen to port " << port << " for TCP.\n";
|
||||
PR_Close(socket);
|
||||
delete socket;
|
||||
return PT(Connection)();
|
||||
}
|
||||
|
||||
|
|
@ -167,22 +148,13 @@ open_TCP_server_rendezvous(int port, int backlog) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PT(Connection) ConnectionManager::
|
||||
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 "
|
||||
<< address.get_ip_string() << " on port " << address.get_port() << "\n";
|
||||
PR_Close(socket);
|
||||
delete socket;
|
||||
return PT(Connection)();
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +171,7 @@ open_TCP_client_connection(const NetAddress &address, int timeout_ms) {
|
|||
// Function: ConnectionManager::open_TCP_client_connection
|
||||
// Access: Public
|
||||
// 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(Connection) ConnectionManager::
|
||||
|
|
@ -238,42 +210,33 @@ close_connection(const PT(Connection) &connection) {
|
|||
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);
|
||||
}
|
||||
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.
|
||||
|
||||
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");
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Socket_IP *socket = connection->get_socket();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
@ -305,9 +268,8 @@ get_host_name() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
new_connection(const PT(Connection) &connection) {
|
||||
PR_Lock(_set_mutex);
|
||||
MutexHolder holder(_set_mutex);
|
||||
_connections.insert(connection);
|
||||
PR_Unlock(_set_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -320,9 +282,9 @@ new_connection(const PT(Connection) &connection) {
|
|||
// been reset.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
|
||||
connection_reset(const PT(Connection) &connection, bool okflag) {
|
||||
if (net_cat.is_info()) {
|
||||
if (errcode == 0) {
|
||||
if (okflag) {
|
||||
net_cat.info()
|
||||
<< "Connection " << (void *)connection
|
||||
<< " was closed normally by the other end";
|
||||
|
|
@ -330,33 +292,8 @@ connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
|
|||
} else {
|
||||
net_cat.info()
|
||||
<< "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
|
||||
|
|
@ -374,9 +311,8 @@ connection_reset(const PT(Connection) &connection, PRErrorCode errcode) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
add_reader(ConnectionReader *reader) {
|
||||
PR_Lock(_set_mutex);
|
||||
MutexHolder holder(_set_mutex);
|
||||
_readers.insert(reader);
|
||||
PR_Unlock(_set_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -387,9 +323,8 @@ add_reader(ConnectionReader *reader) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
remove_reader(ConnectionReader *reader) {
|
||||
PR_Lock(_set_mutex);
|
||||
MutexHolder holder(_set_mutex);
|
||||
_readers.erase(reader);
|
||||
PR_Unlock(_set_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -400,9 +335,8 @@ remove_reader(ConnectionReader *reader) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
add_writer(ConnectionWriter *writer) {
|
||||
PR_Lock(_set_mutex);
|
||||
MutexHolder holder(_set_mutex);
|
||||
_writers.insert(writer);
|
||||
PR_Unlock(_set_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -413,7 +347,6 @@ add_writer(ConnectionWriter *writer) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionManager::
|
||||
remove_writer(ConnectionWriter *writer) {
|
||||
PR_Lock(_set_mutex);
|
||||
MutexHolder holder(_set_mutex);
|
||||
_writers.erase(writer);
|
||||
PR_Unlock(_set_mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include "connection.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pset.h"
|
||||
|
||||
#include <prlock.h>
|
||||
#include <prerror.h>
|
||||
#include "pmutex.h"
|
||||
|
||||
class NetAddress;
|
||||
class ConnectionReader;
|
||||
|
|
@ -69,7 +67,7 @@ PUBLISHED:
|
|||
protected:
|
||||
void new_connection(const PT(Connection) &connection);
|
||||
virtual void connection_reset(const PT(Connection) &connection,
|
||||
PRErrorCode errcode);
|
||||
bool okflag);
|
||||
|
||||
void add_reader(ConnectionReader *reader);
|
||||
void remove_reader(ConnectionReader *reader);
|
||||
|
|
@ -82,7 +80,7 @@ protected:
|
|||
Connections _connections;
|
||||
Readers _readers;
|
||||
Writers _writers;
|
||||
PRLock *_set_mutex;
|
||||
Mutex _set_mutex;
|
||||
|
||||
private:
|
||||
friend class ConnectionReader;
|
||||
|
|
|
|||
|
|
@ -21,20 +21,17 @@
|
|||
#include "netDatagram.h"
|
||||
#include "datagramTCPHeader.h"
|
||||
#include "datagramUDPHeader.h"
|
||||
#include "pprerror.h"
|
||||
#include "config_net.h"
|
||||
#include "trueClock.h"
|
||||
|
||||
#include "socket_udp.h"
|
||||
#include "socket_tcp.h"
|
||||
#include "mutexHolder.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;
|
||||
|
||||
// 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
|
||||
|
|
@ -56,7 +53,7 @@ SocketInfo(const PT(Connection) &connection) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool ConnectionReader::SocketInfo::
|
||||
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
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PRFileDesc *ConnectionReader::SocketInfo::
|
||||
Socket_IP *ConnectionReader::SocketInfo::
|
||||
get_socket() const {
|
||||
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
|
||||
// Access: Public
|
||||
|
|
@ -83,10 +103,6 @@ ConnectionReader(ConnectionManager *manager, int num_threads) :
|
|||
_manager(manager)
|
||||
{
|
||||
#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
|
||||
if (num_threads != 0) {
|
||||
net_cat.error()
|
||||
|
|
@ -101,36 +117,20 @@ ConnectionReader(ConnectionManager *manager, int num_threads) :
|
|||
_polling = (num_threads <= 0);
|
||||
|
||||
_shutdown = false;
|
||||
_startup_mutex = PR_NewLock();
|
||||
|
||||
_next_index = 0;
|
||||
_num_results = 0;
|
||||
_select_mutex = PR_NewLock();
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
PR_Unlock(_startup_mutex);
|
||||
for (i = 0; i < num_threads; i++) {
|
||||
_threads[i]->start(TP_normal, true, true);
|
||||
}
|
||||
|
||||
_manager->add_reader(this);
|
||||
}
|
||||
|
|
@ -166,10 +166,6 @@ ConnectionReader::
|
|||
sinfo->_connection.clear();
|
||||
}
|
||||
}
|
||||
|
||||
PR_DestroyLock(_startup_mutex);
|
||||
PR_DestroyLock(_select_mutex);
|
||||
PR_DestroyLock(_sockets_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -190,24 +186,21 @@ ConnectionReader::
|
|||
// will by any thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ConnectionReader::
|
||||
add_connection(const PT(Connection) &connection) {
|
||||
add_connection(Connection *connection) {
|
||||
nassertr(connection != (Connection *)NULL, false);
|
||||
|
||||
PR_Lock(_sockets_mutex);
|
||||
MutexHolder holder(_sockets_mutex);
|
||||
|
||||
// Make sure it's not already on the _sockets list.
|
||||
Sockets::const_iterator si;
|
||||
for (si = _sockets.begin(); si != _sockets.end(); ++si) {
|
||||
if ((*si)->_connection == connection) {
|
||||
// Whoops, already there.
|
||||
PR_Unlock(_sockets_mutex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_sockets.push_back(new SocketInfo(connection));
|
||||
_reexamine_sockets = true;
|
||||
PR_Unlock(_sockets_mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -224,8 +217,8 @@ add_connection(const PT(Connection) &connection) {
|
|||
// at will by any thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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.
|
||||
Sockets::iterator si;
|
||||
|
|
@ -234,14 +227,11 @@ remove_connection(const PT(Connection) &connection) {
|
|||
++si;
|
||||
}
|
||||
if (si == _sockets.end()) {
|
||||
PR_Unlock(_sockets_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
_removed_sockets.push_back(*si);
|
||||
_sockets.erase(si);
|
||||
_reexamine_sockets = true;
|
||||
PR_Unlock(_sockets_mutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -258,8 +248,8 @@ remove_connection(const PT(Connection) &connection) {
|
|||
// the connection.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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
|
||||
// about.
|
||||
|
|
@ -270,13 +260,11 @@ is_connection_ok(const PT(Connection) &connection) {
|
|||
}
|
||||
if (si == _sockets.end()) {
|
||||
// Don't know that connection.
|
||||
PR_Unlock(_sockets_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
SocketInfo *sinfo = (*si);
|
||||
bool is_ok = !sinfo->_error;
|
||||
PR_Unlock(_sockets_mutex);
|
||||
|
||||
return is_ok;
|
||||
}
|
||||
|
|
@ -299,14 +287,14 @@ poll() {
|
|||
return;
|
||||
}
|
||||
|
||||
SocketInfo *sinfo = get_next_available_socket(PR_INTERVAL_NO_WAIT, -2);
|
||||
SocketInfo *sinfo = get_next_available_socket(false, -2);
|
||||
if (sinfo != (SocketInfo *)NULL) {
|
||||
double max_poll_cycle = get_max_poll_cycle();
|
||||
if (max_poll_cycle < 0.0) {
|
||||
// Continue to read all data.
|
||||
while (sinfo != (SocketInfo *)NULL) {
|
||||
process_incoming_data(sinfo);
|
||||
sinfo = get_next_available_socket(PR_INTERVAL_NO_WAIT, -2);
|
||||
sinfo = get_next_available_socket(false, -2);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -319,7 +307,7 @@ poll() {
|
|||
if (global_clock->get_short_time() >= stop) {
|
||||
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.
|
||||
Threads::iterator 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
|
||||
// future polls.
|
||||
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
|
||||
// Access: Protected, Virtual
|
||||
// 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::
|
||||
process_incoming_data(SocketInfo *sinfo) {
|
||||
|
|
@ -523,21 +482,17 @@ process_incoming_data(SocketInfo *sinfo) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionReader::
|
||||
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.
|
||||
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);
|
||||
return;
|
||||
|
||||
|
|
@ -563,7 +518,7 @@ process_incoming_udp_data(SocketInfo *sinfo) {
|
|||
|
||||
DatagramUDPHeader header(buffer);
|
||||
|
||||
PRInt8 *dp = buffer + datagram_udp_header_size;
|
||||
char *dp = buffer + datagram_udp_header_size;
|
||||
bytes_read -= datagram_udp_header_size;
|
||||
|
||||
NetDatagram datagram(dp, bytes_read);
|
||||
|
|
@ -594,44 +549,20 @@ process_incoming_udp_data(SocketInfo *sinfo) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionReader::
|
||||
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.
|
||||
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.
|
||||
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);
|
||||
int bytes_read =
|
||||
socket->RecvData(buffer + header_bytes_read,
|
||||
_tcp_header_size - header_bytes_read);
|
||||
|
||||
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;
|
||||
|
||||
} else if (bytes_read == 0) {
|
||||
if (bytes_read <= 0) {
|
||||
// The socket was closed. Report that and return.
|
||||
if (_manager != (ConnectionManager *)NULL) {
|
||||
_manager->connection_reset(sinfo->_connection, 0);
|
||||
|
|
@ -655,41 +586,20 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
|
|||
}
|
||||
|
||||
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.
|
||||
NetDatagram datagram;
|
||||
|
||||
while (!_shutdown && (int)datagram.get_length() < size) {
|
||||
PRInt32 bytes_read;
|
||||
int 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;
|
||||
socket->RecvData(buffer, min(read_buffer_size,
|
||||
(int)(size - datagram.get_length())));
|
||||
char *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);
|
||||
}
|
||||
|
||||
} 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.
|
||||
if (_manager != (ConnectionManager *)NULL) {
|
||||
_manager->connection_reset(sinfo->_connection, 0);
|
||||
|
|
@ -698,8 +608,8 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
|
|||
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);
|
||||
|
||||
if (bytes_read > datagram_bytes) {
|
||||
|
|
@ -725,7 +635,7 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
|
|||
<< "Ignoring invalid TCP datagram.\n";
|
||||
} else {
|
||||
datagram.set_connection(sinfo->_connection);
|
||||
datagram.set_address(NetAddress(addr));
|
||||
datagram.set_address(NetAddress(socket->GetPeerName()));
|
||||
receive_datagram(datagram);
|
||||
}
|
||||
}
|
||||
|
|
@ -737,21 +647,17 @@ process_incoming_tcp_data(SocketInfo *sinfo) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionReader::
|
||||
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.
|
||||
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);
|
||||
return;
|
||||
|
||||
|
|
@ -789,29 +695,14 @@ process_raw_incoming_udp_data(SocketInfo *sinfo) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionReader::
|
||||
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.
|
||||
PRInt8 buffer[read_buffer_size];
|
||||
PRInt32 bytes_read;
|
||||
char buffer[read_buffer_size];
|
||||
int bytes_read = socket->RecvData(buffer, read_buffer_size);
|
||||
|
||||
if (PR_GetSockName(socket, &addr) != PR_SUCCESS) {
|
||||
pprerror("PR_GetSockName");
|
||||
}
|
||||
|
||||
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.
|
||||
if (_manager != (ConnectionManager *)NULL) {
|
||||
_manager->connection_reset(sinfo->_connection, 0);
|
||||
|
|
@ -833,24 +724,10 @@ process_raw_incoming_tcp_data(SocketInfo *sinfo) {
|
|||
}
|
||||
|
||||
datagram.set_connection(sinfo->_connection);
|
||||
datagram.set_address(NetAddress(addr));
|
||||
datagram.set_address(NetAddress(socket->GetPeerName()));
|
||||
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
|
||||
// Access: Private
|
||||
|
|
@ -858,24 +735,13 @@ thread_start(void *data) {
|
|||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionReader::
|
||||
thread_run() {
|
||||
thread_run(int thread_index) {
|
||||
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) {
|
||||
SocketInfo *sinfo =
|
||||
get_next_available_socket(PR_INTERVAL_NO_TIMEOUT,
|
||||
current_thread_index);
|
||||
get_next_available_socket(false, thread_index);
|
||||
if (sinfo != (SocketInfo *)NULL) {
|
||||
process_incoming_data(sinfo);
|
||||
}
|
||||
|
|
@ -892,59 +758,29 @@ thread_run() {
|
|||
//
|
||||
// This function may block indefinitely if it is being
|
||||
// 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::
|
||||
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
|
||||
// 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 {
|
||||
// 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.
|
||||
while (!_shutdown && _num_results > 0) {
|
||||
nassertr(_next_index < num_sockets, NULL);
|
||||
nassertr(_next_index < (int)_selecting_sockets.size(), NULL);
|
||||
int i = _next_index;
|
||||
_next_index++;
|
||||
|
||||
if (_poll[i].out_flags != 0) {
|
||||
if (_fdset.IsSetFor(*_selecting_sockets[i]->get_socket())) {
|
||||
_num_results--;
|
||||
SocketInfo *sinfo = _polled_sockets[i];
|
||||
SocketInfo *sinfo = _selecting_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;
|
||||
}
|
||||
// Some noise on this socket.
|
||||
sinfo->_busy = true;
|
||||
return sinfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -952,93 +788,70 @@ get_next_available_socket(PRIntervalTime timeout,
|
|||
do {
|
||||
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
|
||||
// about to do the poll. That way, if any new sockets come
|
||||
// available while we're polling, we can service them.
|
||||
PR_AtomicSet(&_currently_polling_thread, current_thread_index);
|
||||
AtomicAdjust::set(_currently_polling_thread, current_thread_index);
|
||||
|
||||
rebuild_select_list();
|
||||
|
||||
if (_reexamine_sockets) {
|
||||
_reexamine_sockets = false;
|
||||
rebuild_poll_list();
|
||||
num_sockets = _polled_sockets.size();
|
||||
nassertr(num_sockets == (int)_poll.size(), NULL);
|
||||
}
|
||||
|
||||
// Now we can execute PR_Poll(). This basically maps to a Unix
|
||||
// select() call.
|
||||
// Now we can execute the select.
|
||||
_num_results = 0;
|
||||
_next_index = 0;
|
||||
|
||||
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;
|
||||
|
||||
} 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);
|
||||
|
||||
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
|
||||
// on it, or (b) return from PR_Poll() with no sockets available.
|
||||
} while (!_shutdown && _num_results > 0);
|
||||
|
||||
PR_Unlock(_select_mutex);
|
||||
return (SocketInfo *)NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConnectionReader::rebuild_poll_list
|
||||
// Function: ConnectionReader::rebuild_select_list
|
||||
// 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::
|
||||
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;
|
||||
for (si = _sockets.begin(); si != _sockets.end(); ++si) {
|
||||
SocketInfo *sinfo = (*si);
|
||||
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);
|
||||
}
|
||||
|
||||
PR_Unlock(_sockets_mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,15 @@
|
|||
#include "connection.h"
|
||||
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include <prio.h>
|
||||
#include <prthread.h>
|
||||
#include <prlock.h>
|
||||
#include "pmutex.h"
|
||||
#include "pvector.h"
|
||||
#include "pset.h"
|
||||
#include "socket_fdset.h"
|
||||
|
||||
class NetDatagram;
|
||||
class ConnectionManager;
|
||||
class Socket_Address;
|
||||
class Socket_IP;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ConnectionReader
|
||||
|
|
@ -72,9 +72,9 @@ PUBLISHED:
|
|||
ConnectionReader(ConnectionManager *manager, int num_threads);
|
||||
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();
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ protected:
|
|||
public:
|
||||
SocketInfo(const PT(Connection) &connection);
|
||||
bool is_udp() const;
|
||||
PRFileDesc *get_socket() const;
|
||||
Socket_IP *get_socket() const;
|
||||
|
||||
PT(Connection) _connection;
|
||||
bool _busy;
|
||||
|
|
@ -113,13 +113,12 @@ protected:
|
|||
virtual void process_raw_incoming_tcp_data(SocketInfo *sinfo);
|
||||
|
||||
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:
|
||||
ConnectionManager *_manager;
|
||||
|
|
@ -129,27 +128,34 @@ private:
|
|||
int _tcp_header_size;
|
||||
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;
|
||||
PRLock *_startup_mutex;
|
||||
bool _polling;
|
||||
|
||||
// These structures are used to manage polling for noise on
|
||||
// These structures are used to manage selecting for noise on
|
||||
// available sockets.
|
||||
typedef pvector<PRPollDesc> Poll;
|
||||
Socket_fdset _fdset;
|
||||
typedef pvector<SocketInfo *> Sockets;
|
||||
Poll _poll;
|
||||
Sockets _polled_sockets;
|
||||
Sockets _selecting_sockets;
|
||||
int _next_index;
|
||||
int _num_results;
|
||||
// Threads go to sleep on this mutex waiting for their chance to
|
||||
// read a socket.
|
||||
PRLock *_select_mutex;
|
||||
Mutex _select_mutex;
|
||||
|
||||
// This is atomically updated with the index (in _threads) of the
|
||||
// thread that is currently waiting on the PR_Poll() call. It
|
||||
// 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
|
||||
// know about.
|
||||
|
|
@ -157,14 +163,12 @@ private:
|
|||
// This is the list of recently-removed sockets. We can't actually
|
||||
// delete them until they're no longer _busy.
|
||||
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.
|
||||
PRLock *_sockets_mutex;
|
||||
Mutex _sockets_mutex;
|
||||
|
||||
|
||||
friend class ConnectionManager;
|
||||
friend class ConnectionManager;
|
||||
friend class ReaderThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,11 +19,33 @@
|
|||
#include "connectionWriter.h"
|
||||
#include "connectionManager.h"
|
||||
#include "datagramTCPHeader.h"
|
||||
#include "pprerror.h"
|
||||
#include "config_net.h"
|
||||
|
||||
#include "socket_tcp.h"
|
||||
#include "socket_udp.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
|
||||
|
|
@ -57,18 +79,14 @@ ConnectionWriter(ConnectionManager *manager, int num_threads) :
|
|||
_tcp_header_size = datagram_tcp16_header_size;
|
||||
_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);
|
||||
}
|
||||
for (i = 0; i < num_threads; i++) {
|
||||
_threads[i]->start(TP_normal, true, true);
|
||||
}
|
||||
|
||||
_manager->add_writer(this);
|
||||
}
|
||||
|
|
@ -91,16 +109,7 @@ ConnectionWriter::
|
|||
// Now wait for all threads to terminate.
|
||||
Threads::iterator 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::
|
||||
send(const Datagram &datagram, const PT(Connection) &connection) {
|
||||
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);
|
||||
copy.set_connection(connection);
|
||||
|
|
@ -159,10 +168,9 @@ bool ConnectionWriter::
|
|||
send(const Datagram &datagram, const PT(Connection) &connection,
|
||||
const NetAddress &address) {
|
||||
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()
|
||||
<< "Attempt to send UDP datagram of " << datagram.get_length()
|
||||
<< " bytes, more than the\n"
|
||||
|
|
@ -299,19 +307,6 @@ clear_manager() {
|
|||
_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
|
||||
// Access: Private
|
||||
|
|
@ -319,7 +314,7 @@ thread_start(void *data) {
|
|||
// thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ConnectionWriter::
|
||||
thread_run() {
|
||||
thread_run(int thread_index) {
|
||||
nassertv(!_immediate);
|
||||
|
||||
NetDatagram datagram;
|
||||
|
|
|
|||
|
|
@ -20,13 +20,10 @@
|
|||
#define CONNECTIONWRITER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "datagramQueue.h"
|
||||
#include "connection.h"
|
||||
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include <prthread.h>
|
||||
#include "thread.h"
|
||||
#include "pvector.h"
|
||||
|
||||
class ConnectionManager;
|
||||
|
|
@ -38,7 +35,7 @@ class NetAddress;
|
|||
// various TCP or UDP sockets.
|
||||
//
|
||||
// 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
|
||||
// construction time and cannot be changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -70,8 +67,7 @@ protected:
|
|||
void clear_manager();
|
||||
|
||||
private:
|
||||
static void thread_start(void *data);
|
||||
void thread_run();
|
||||
void thread_run(int thread_index);
|
||||
bool send_datagram(const NetDatagram &datagram);
|
||||
|
||||
protected:
|
||||
|
|
@ -82,11 +78,22 @@ private:
|
|||
int _tcp_header_size;
|
||||
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;
|
||||
|
||||
bool _immediate;
|
||||
|
||||
friend class ConnectionManager;
|
||||
friend class ConnectionManager;
|
||||
friend class WriterThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "datagramQueue.h"
|
||||
#include "config_net.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DatagramQueue::Constructor
|
||||
|
|
@ -25,10 +26,8 @@
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DatagramQueue::
|
||||
DatagramQueue() {
|
||||
DatagramQueue() : _cv(_cvlock) {
|
||||
_shutdown = false;
|
||||
_cvlock = PR_NewLock();
|
||||
_cv = PR_NewCondVar(_cvlock);
|
||||
_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
|
||||
// down (and waiting for any associated threads to terminate).
|
||||
nassertv(_shutdown);
|
||||
|
||||
PR_DestroyCondVar(_cv);
|
||||
PR_DestroyLock(_cvlock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -61,10 +57,10 @@ void DatagramQueue::
|
|||
shutdown() {
|
||||
// Notify all of our threads that we're shutting down. This will
|
||||
// cause any thread blocking on extract() to return false.
|
||||
PR_Lock(_cvlock);
|
||||
MutexHolder holder(_cvlock);
|
||||
|
||||
_shutdown = true;
|
||||
PR_NotifyAllCondVar(_cv);
|
||||
PR_Unlock(_cvlock);
|
||||
_cv.signal_all();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -79,17 +75,14 @@ shutdown() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool DatagramQueue::
|
||||
insert(const NetDatagram &data) {
|
||||
PR_Lock(_cvlock);
|
||||
MutexHolder holder(_cvlock);
|
||||
|
||||
bool enqueue_ok = ((int)_queue.size() < _max_queue_size);
|
||||
if (enqueue_ok) {
|
||||
#ifdef __ICL
|
||||
_queue.push_back(new NetDatagram(data));
|
||||
#else
|
||||
_queue.push_back(data);
|
||||
#endif
|
||||
}
|
||||
PR_NotifyCondVar(_cv);
|
||||
PR_Unlock(_cvlock);
|
||||
_cv.signal();
|
||||
|
||||
return enqueue_ok;
|
||||
}
|
||||
|
||||
|
|
@ -118,27 +111,20 @@ extract(NetDatagram &result) {
|
|||
// connection pointer--we're about to go to sleep for a while.
|
||||
result.clear();
|
||||
|
||||
PR_Lock(_cvlock);
|
||||
MutexHolder holder(_cvlock);
|
||||
|
||||
while (_queue.empty() && !_shutdown) {
|
||||
PR_WaitCondVar(_cv, PR_INTERVAL_NO_TIMEOUT);
|
||||
_cv.wait();
|
||||
}
|
||||
|
||||
if (_shutdown) {
|
||||
PR_Unlock(_cvlock);
|
||||
return false;
|
||||
}
|
||||
|
||||
nassertr(!_queue.empty(), false);
|
||||
#ifdef __ICL
|
||||
NetDatagram *ptr = _queue.front();
|
||||
result = *ptr;
|
||||
delete ptr;
|
||||
#else
|
||||
result = _queue.front();
|
||||
#endif
|
||||
_queue.pop_front();
|
||||
|
||||
PR_Unlock(_cvlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -156,9 +142,8 @@ extract(NetDatagram &result) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DatagramQueue::
|
||||
set_max_queue_size(int max_size) {
|
||||
PR_Lock(_cvlock);
|
||||
MutexHolder holder(_cvlock);
|
||||
_max_queue_size = max_size;
|
||||
PR_Unlock(_cvlock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -179,8 +164,7 @@ get_max_queue_size() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int DatagramQueue::
|
||||
get_current_queue_size() const {
|
||||
PR_Lock(_cvlock);
|
||||
MutexHolder holder(_cvlock);
|
||||
int size = _queue.size();
|
||||
PR_Unlock(_cvlock);
|
||||
return size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,8 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
#include "netDatagram.h"
|
||||
|
||||
#include <prlock.h>
|
||||
#include <prcvar.h>
|
||||
#include "pmutex.h"
|
||||
#include "conditionVarFull.h"
|
||||
#include "pdeque.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,17 +46,10 @@ public:
|
|||
int get_current_queue_size() const;
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
QueueType _queue;
|
||||
bool _shutdown;
|
||||
int _max_queue_size;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ DatagramTCPHeader(const NetDatagram &datagram, int header_size) {
|
|||
|
||||
case datagram_tcp16_header_size:
|
||||
{
|
||||
PRUint16 size = str.length();
|
||||
PN_uint16 size = str.length();
|
||||
nassertv(size == str.length());
|
||||
_header.add_uint16(size);
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ DatagramTCPHeader(const NetDatagram &datagram, int header_size) {
|
|||
|
||||
case datagram_tcp32_header_size:
|
||||
{
|
||||
PRUint32 size = str.length();
|
||||
PN_uint32 size = str.length();
|
||||
nassertv(size == str.length());
|
||||
_header.add_uint32(size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,11 +24,10 @@
|
|||
#include "netDatagram.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;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@
|
|||
DatagramUDPHeader::
|
||||
DatagramUDPHeader(const NetDatagram &datagram) {
|
||||
const string &str = datagram.get_message();
|
||||
PRUint16 checksum = 0;
|
||||
PN_uint16 checksum = 0;
|
||||
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.
|
||||
|
|
@ -64,9 +64,9 @@ bool DatagramUDPHeader::
|
|||
verify_datagram(const NetDatagram &datagram) const {
|
||||
const string &str = datagram.get_message();
|
||||
|
||||
PRUint16 checksum = 0;
|
||||
PN_uint16 checksum = 0;
|
||||
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()) {
|
||||
|
|
|
|||
|
|
@ -24,10 +24,9 @@
|
|||
#include "netDatagram.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;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,8 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "netAddress.h"
|
||||
#include "pprerror.h"
|
||||
#include "config_net.h"
|
||||
|
||||
#include <prio.h>
|
||||
#include <prnetdb.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NetAddress::Constructor
|
||||
|
|
@ -31,19 +27,18 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
NetAddress::
|
||||
NetAddress() {
|
||||
PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &_addr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NetAddress::Constructor
|
||||
// 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
|
||||
// code; instead, create a default NetAddress and use
|
||||
// one of the set_*() functions to set up an address.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
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::
|
||||
clear() {
|
||||
PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &_addr);
|
||||
_addr.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -187,7 +95,7 @@ clear() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int NetAddress::
|
||||
get_port() const {
|
||||
return PR_ntohs(_addr.inet.port);
|
||||
return _addr.get_port();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -198,7 +106,7 @@ get_port() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void NetAddress::
|
||||
set_port(int port) {
|
||||
PR_InitializeNetAddr(PR_IpAddrNull, port, &_addr);
|
||||
_addr.set_port(port);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -209,17 +117,7 @@ set_port(int port) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
string NetAddress::
|
||||
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::
|
||||
get_ip() const {
|
||||
return PR_ntohl(_addr.inet.ip);
|
||||
return _addr.GetIPAddressRaw();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -244,7 +142,8 @@ get_ip() const {
|
|||
PN_uint8 NetAddress::
|
||||
get_ip_component(int n) const {
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
@ -252,11 +151,11 @@ get_ip_component(int n) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NetAddress::get_addr
|
||||
// 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 {
|
||||
return (PRNetAddr *)&_addr;
|
||||
return _addr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
#include "numeric_types.h"
|
||||
|
||||
#include <prio.h>
|
||||
#include "socket_address.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : NetAddress
|
||||
|
|
@ -32,7 +31,7 @@
|
|||
class EXPCL_PANDA NetAddress {
|
||||
PUBLISHED:
|
||||
NetAddress();
|
||||
NetAddress(const PRNetAddr &addr);
|
||||
NetAddress(const Socket_Address &addr);
|
||||
|
||||
bool set_any(int port);
|
||||
bool set_localhost(int port);
|
||||
|
|
@ -46,12 +45,12 @@ PUBLISHED:
|
|||
PN_uint32 get_ip() const;
|
||||
PN_uint8 get_ip_component(int n) const;
|
||||
|
||||
PRNetAddr *get_addr() const;
|
||||
const Socket_Address &get_addr() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
PRNetAddr _addr;
|
||||
Socket_Address _addr;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const NetAddress &addr) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
#include "config_net.cxx"
|
||||
#include "pprerror.cxx"
|
||||
#include "connection.cxx"
|
||||
#include "connectionListener.cxx"
|
||||
#include "connectionManager.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
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -25,8 +25,6 @@
|
|||
#include "connection.h"
|
||||
#include "netAddress.h"
|
||||
#include "queuedReturn.h"
|
||||
|
||||
#include <prlock.h>
|
||||
#include "pdeque.h"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ get_reset_connection(PT(Connection) &connection) {
|
|||
// been reset.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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
|
||||
// does, it probably just means the user isn't bothering to track
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
#include "queuedReturn.h"
|
||||
#include "pdeque.h"
|
||||
|
||||
#include <prlock.h>
|
||||
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, QueuedReturn< PT(Connection) >);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -53,7 +51,7 @@ PUBLISHED:
|
|||
|
||||
protected:
|
||||
virtual void connection_reset(const PT(Connection) &connection,
|
||||
PRErrorCode errcode);
|
||||
bool okflag);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "queuedConnectionReader.h"
|
||||
#include "config_net.h"
|
||||
#include "trueClock.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: QueuedConnectionReader::Constructor
|
||||
|
|
@ -30,7 +31,6 @@ QueuedConnectionReader(ConnectionManager *manager, int num_threads) :
|
|||
ConnectionReader(manager, num_threads)
|
||||
{
|
||||
#ifdef SIMULATE_NETWORK_DELAY
|
||||
_dd_mutex = PR_NewLock();
|
||||
_delay_active = false;
|
||||
_min_delay = 0.0;
|
||||
_delay_variance = 0.0;
|
||||
|
|
@ -47,10 +47,6 @@ QueuedConnectionReader::
|
|||
// We call shutdown() here to guarantee that all threads are gone
|
||||
// before the QueuedReturn destructs.
|
||||
shutdown();
|
||||
|
||||
#ifdef SIMULATE_NETWORK_DELAY
|
||||
PR_DestroyLock(_dd_mutex);
|
||||
#endif // SIMULATE_NETWORK_DELAY
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -149,11 +145,10 @@ receive_datagram(const NetDatagram &datagram) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void QueuedConnectionReader::
|
||||
start_delay(double min_delay, double max_delay) {
|
||||
PR_Lock(_dd_mutex);
|
||||
MutexHolder holder(_dd_mutex);
|
||||
_min_delay = min_delay;
|
||||
_delay_variance = max(max_delay - min_delay, 0.0);
|
||||
_delay_active = true;
|
||||
PR_Unlock(_dd_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -165,7 +160,7 @@ start_delay(double min_delay, double max_delay) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void QueuedConnectionReader::
|
||||
stop_delay() {
|
||||
PR_Lock(_dd_mutex);
|
||||
MutexHolder holder(_dd_mutex);
|
||||
_delay_active = false;
|
||||
|
||||
// Copy the entire contents of the delay queue to the normal queue.
|
||||
|
|
@ -177,8 +172,6 @@ stop_delay() {
|
|||
}
|
||||
_delayed.pop_front();
|
||||
}
|
||||
|
||||
PR_Unlock(_dd_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -191,7 +184,7 @@ stop_delay() {
|
|||
void QueuedConnectionReader::
|
||||
get_delayed() {
|
||||
if (_delay_active) {
|
||||
PR_Lock(_dd_mutex);
|
||||
MutexHolder holder(_dd_mutex);
|
||||
double now = TrueClock::get_global_ptr()->get_short_time();
|
||||
while (!_delayed.empty()) {
|
||||
const DelayedDatagram &dd = _delayed.front();
|
||||
|
|
@ -205,7 +198,6 @@ get_delayed() {
|
|||
}
|
||||
_delayed.pop_front();
|
||||
}
|
||||
PR_Unlock(_dd_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +215,7 @@ delay_datagram(const NetDatagram &datagram) {
|
|||
<< "QueuedConnectionReader queue full!\n";
|
||||
}
|
||||
} else {
|
||||
PR_Lock(_dd_mutex);
|
||||
MutexHolder holder(_dd_mutex);
|
||||
// Check the delay_active flag again, now that we have grabbed the
|
||||
// mutex.
|
||||
if (!_delay_active) {
|
||||
|
|
@ -244,7 +236,6 @@ delay_datagram(const NetDatagram &datagram) {
|
|||
dd._reveal_time = reveal_time;
|
||||
dd._datagram = datagram;
|
||||
}
|
||||
PR_Unlock(_dd_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@
|
|||
#include "connectionReader.h"
|
||||
#include "netDatagram.h"
|
||||
#include "queuedReturn.h"
|
||||
|
||||
#include <prlock.h>
|
||||
#include "pmutex.h"
|
||||
#include "pdeque.h"
|
||||
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, QueuedReturn<NetDatagram>);
|
||||
|
|
@ -67,7 +66,7 @@ private:
|
|||
NetDatagram _datagram;
|
||||
};
|
||||
|
||||
PRLock *_dd_mutex;
|
||||
Mutex _dd_mutex;
|
||||
typedef pdeque<DelayedDatagram> Delayed;
|
||||
Delayed _delayed;
|
||||
bool _delay_active;
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_net.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: QueuedReturn::set_max_queue_size
|
||||
|
|
@ -35,9 +32,8 @@
|
|||
template<class Thing>
|
||||
void QueuedReturn<Thing>::
|
||||
set_max_queue_size(int max_size) {
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
_max_queue_size = max_size;
|
||||
PR_Unlock(_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -60,9 +56,8 @@ get_max_queue_size() const {
|
|||
template<class Thing>
|
||||
int QueuedReturn<Thing>::
|
||||
get_current_queue_size() const {
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
int size = _things.size();
|
||||
PR_Unlock(_mutex);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +95,6 @@ reset_overflow_flag() {
|
|||
template<class Thing>
|
||||
QueuedReturn<Thing>::
|
||||
QueuedReturn() {
|
||||
_mutex = PR_NewLock();
|
||||
_available = false;
|
||||
_max_queue_size = get_net_max_response_queue();
|
||||
_overflow_flag = false;
|
||||
|
|
@ -114,7 +108,6 @@ QueuedReturn() {
|
|||
template<class Thing>
|
||||
QueuedReturn<Thing>::
|
||||
~QueuedReturn() {
|
||||
PR_DestroyLock(_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -145,18 +138,16 @@ thing_available() const {
|
|||
template<class Thing>
|
||||
bool QueuedReturn<Thing>::
|
||||
get_thing(Thing &result) {
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
if (_things.empty()) {
|
||||
// Huh. Nothing after all.
|
||||
_available = false;
|
||||
PR_Unlock(_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = _things.front();
|
||||
_things.pop_front();
|
||||
_available = !_things.empty();
|
||||
PR_Unlock(_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +161,7 @@ get_thing(Thing &result) {
|
|||
template<class Thing>
|
||||
bool QueuedReturn<Thing>::
|
||||
enqueue_thing(const Thing &thing) {
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
bool enqueue_ok = ((int)_things.size() < _max_queue_size);
|
||||
if (enqueue_ok) {
|
||||
_things.push_back(thing);
|
||||
|
|
@ -178,7 +169,6 @@ enqueue_thing(const Thing &thing) {
|
|||
_overflow_flag = true;
|
||||
}
|
||||
_available = true;
|
||||
PR_Unlock(_mutex);
|
||||
|
||||
return enqueue_ok;
|
||||
}
|
||||
|
|
@ -195,7 +185,7 @@ enqueue_thing(const Thing &thing) {
|
|||
template<class Thing>
|
||||
bool QueuedReturn<Thing>::
|
||||
enqueue_unique_thing(const Thing &thing) {
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
bool enqueue_ok = ((int)_things.size() < _max_queue_size);
|
||||
if (enqueue_ok) {
|
||||
if (find(_things.begin(), _things.end(), thing) == _things.end()) {
|
||||
|
|
@ -210,7 +200,6 @@ enqueue_unique_thing(const Thing &thing) {
|
|||
_overflow_flag = true;
|
||||
}
|
||||
_available = true;
|
||||
PR_Unlock(_mutex);
|
||||
|
||||
return enqueue_ok;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,12 @@
|
|||
#include "connectionListener.h"
|
||||
#include "connection.h"
|
||||
#include "netAddress.h"
|
||||
|
||||
#include <prlock.h>
|
||||
#include "pmutex.h"
|
||||
#include "pdeque.h"
|
||||
#include "config_net.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : QueuedReturn
|
||||
|
|
@ -56,7 +59,7 @@ protected:
|
|||
bool enqueue_unique_thing(const Thing &thing);
|
||||
|
||||
private:
|
||||
PRLock *_mutex;
|
||||
Mutex _mutex;
|
||||
pdeque<Thing> _things;
|
||||
bool _available;
|
||||
int _max_queue_size;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "recentConnectionReader.h"
|
||||
#include "config_net.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RecentConnectionReader::Constructor
|
||||
|
|
@ -33,7 +34,6 @@ RecentConnectionReader(ConnectionManager *manager) :
|
|||
// this should be impossible, because we can't receive datagrams
|
||||
// before we call add_connection().
|
||||
_available = false;
|
||||
_mutex = PR_NewLock();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -46,8 +46,6 @@ RecentConnectionReader::
|
|||
// We call shutdown() here to guarantee that all threads are gone
|
||||
// before the RecentConnectionReader destructs.
|
||||
shutdown();
|
||||
|
||||
PR_DestroyLock(_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -76,16 +74,14 @@ data_available() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool RecentConnectionReader::
|
||||
get_data(NetDatagram &result) {
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
if (!_available) {
|
||||
// Huh. Nothing after all.
|
||||
PR_Unlock(_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = _datagram;
|
||||
_available = false;
|
||||
PR_Unlock(_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -125,8 +121,7 @@ receive_datagram(const NetDatagram &datagram) {
|
|||
<< " bytes\n";
|
||||
}
|
||||
|
||||
PR_Lock(_mutex);
|
||||
MutexHolder holder(_mutex);
|
||||
_datagram = datagram;
|
||||
_available = true;
|
||||
PR_Unlock(_mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@
|
|||
|
||||
#include "connectionReader.h"
|
||||
#include "netDatagram.h"
|
||||
|
||||
#include <prlock.h>
|
||||
#include "pmutex.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : RecentConnectionReader
|
||||
|
|
@ -53,7 +52,7 @@ protected:
|
|||
private:
|
||||
bool _available;
|
||||
Datagram _datagram;
|
||||
PRLock *_mutex;
|
||||
Mutex _mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "netAddress.h"
|
||||
#include "connection.h"
|
||||
#include "netDatagram.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "pset.h"
|
||||
|
||||
int
|
||||
|
|
@ -99,7 +99,7 @@ main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// Yield the timeslice before we poll again.
|
||||
PR_Sleep(PR_MillisecondsToInterval(100));
|
||||
Thread::sleep(0.1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -22,10 +22,9 @@
|
|||
#include "netAddress.h"
|
||||
#include "connection.h"
|
||||
#include "netDatagram.h"
|
||||
|
||||
#include "clockObject.h"
|
||||
#include "datagram_ui.h"
|
||||
|
||||
#include <prinrval.h>
|
||||
#include "thread.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
|
|
@ -69,12 +68,14 @@ main(int argc, char *argv[]) {
|
|||
|
||||
int num_sent = 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) {
|
||||
// Send the datagram.
|
||||
if (writer.send(datagram, c, host)) {
|
||||
if (writer.send(datagram, c)) {
|
||||
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 "
|
||||
<< num_received << " datagrams.\n";
|
||||
last_reported_time = now;
|
||||
}
|
||||
|
||||
// Yield the timeslice before we poll again.
|
||||
// PR_Sleep(PR_MillisecondsToInterval(1));
|
||||
Thread::sleep(0.001);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
#include "netDatagram.h"
|
||||
|
||||
#include "datagram_ui.h"
|
||||
|
||||
#include <prinrval.h>
|
||||
#include "clockObject.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "pset.h"
|
||||
#include <sys/time.h>
|
||||
|
|
@ -65,8 +65,10 @@ main(int argc, char *argv[]) {
|
|||
|
||||
int num_sent = 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;
|
||||
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 "
|
||||
<< num_received << " datagrams.\n";
|
||||
last_reported_time = now;
|
||||
}
|
||||
|
||||
// Yield the timeslice before we poll again.
|
||||
// PR_Sleep(PR_MillisecondsToInterval(1));
|
||||
Thread::sleep(0.001);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "netAddress.h"
|
||||
#include "connection.h"
|
||||
#include "netDatagram.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "datagram_ui.h"
|
||||
|
||||
#include "pset.h"
|
||||
|
|
@ -119,7 +119,7 @@ main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// Yield the timeslice before we poll again.
|
||||
PR_Sleep(PR_MillisecondsToInterval(100));
|
||||
Thread::sleep(0.1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#begin lib_target
|
||||
#define TARGET pipeline
|
||||
#define USE_PACKAGES threads
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
|
|||
|
|
@ -458,9 +458,14 @@ handle_server_control_message(const PStatServerControlMessage &message) {
|
|||
// has been lost.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PStatClientImpl::
|
||||
connection_reset(const PT(Connection) &connection, PRErrorCode) {
|
||||
connection_reset(const PT(Connection) &connection, bool) {
|
||||
if (connection == _tcp_connection) {
|
||||
_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 {
|
||||
pstats_cat.warning()
|
||||
<< "Ignoring spurious connection_reset() message\n";
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ private:
|
|||
void handle_server_control_message(const PStatServerControlMessage &message);
|
||||
|
||||
virtual void connection_reset(const PT(Connection) &connection,
|
||||
PRErrorCode errcode);
|
||||
bool okflag);
|
||||
|
||||
PStatClient *_client;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "pStatServer.h"
|
||||
#include "pStatReader.h"
|
||||
|
||||
#include "thread.h"
|
||||
#include "config_pstats.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -146,10 +146,7 @@ void PStatServer::
|
|||
main_loop(bool *interrupt_flag) {
|
||||
while (interrupt_flag == (bool *)NULL || !*interrupt_flag) {
|
||||
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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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.
|
||||
close_connection(connection);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void connection_reset(const PT(Connection) &connection,
|
||||
PRErrorCode errcode);
|
||||
bool okflag);
|
||||
|
||||
private:
|
||||
void user_guide_bars_changed();
|
||||
|
|
|
|||
Loading…
Reference in New Issue