⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryptos.h

📁 老外写的加密库cryptlib(版本3.1)
💻 H
📖 第 1 页 / 共 2 页
字号:
#define THREAD_SELF()			pthread_self()
#define THREAD_SAME( thread1, thread2 ) \
								pthread_equal( ( thread1 ), ( thread2 ) )
#define THREAD_SLEEP( ms )		{ \
								struct timeval tv = { 0 }; \
								\
								tv.tv_usec = ( ms ) * 1000; \
								select( 1, NULL, NULL, NULL, &tv ); \
								}
#define THREAD_WAIT( thread )	pthread_join( thread, NULL )
#define THREAD_CLOSE( thread )

/* Yield a thread's timeslice.  This gets rather complex due to a confusion
   of non-portable "portable" Posix functions.  Initially there was
   pthread_yield() from draft 4 of the Posix thread standard in 1990,
   popularised in the DCE threading code and picked up by a number of
   other implementations.  Eventually this was deprecated in favour of
   sched_yield(), however some implementations still do pthread_yield()
   and some implementations use sched_yield() to yield the processes'
   timeslice rather than the thread's timeslice.  The whole is further
   confused by the fact that in some implementations, threads are processes
   (sort of, e.g. Linux's clone()'d threads and Sun LWPs).  In addition Sun
   have their own thr_yield which is part of their UI threads interface and
   that you have to fall back to occasionally.

   Because of this mess, we try for pthread_yield() if possible (since that
   yields the thread's timeslice), fall back to sched_yield() if necessary,
   and add a special workaround for Sun systems.

   "Posix is portable in the sense that you can use a forklift to move the
    printed volumes around" */

#if defined( __osf__ ) || defined( __alpha__ ) || defined( __APPLE__ )
  #define THREAD_YIELD()		pthread_yield_np()
#elif defined( __MVS__ )
  #define THREAD_YIELD()		pthread_yield( NULL )
#elif defined( sun )
  /* Slowaris gets a bit complex, SunOS 4.x always returns -1 and sets errno
     to ENOSYS when sched_yield() is called, so we use this to fall back to
	 the UI interface if necessary */
  #define THREAD_YIELD()		{ if( sched_yield() ) thr_yield(); }
#elif defined( _AIX ) || defined( USE_SCHED_YIELD )
  #define THREAD_YIELD()		sched_yield()
#else
  #define  THREAD_YIELD()		pthread_yield()
#endif /* Not-very-portable Posix portability */

/* OSF1 includes some ghastly kludgery to handle binary compatibility from
   1003.4a to 1003.1c threading functions and inline asm functions with all
   sorts of name mangling and translation of function names and types.
   Unfortunately a straight vanilla compile leaves pthread_self() un-
   prototyped, which means it's implicitly prototyped as returned an int.
   This generates hundreds of warnings of int <-> pointer casting problems,
   so if pthread_self() isn't redefined into one of a dozen different
   mangled versions we prototype it ourselves here */

#if ( defined( __osf__ ) || defined( __alpha__ ) ) && \
	!defined( pthread_self )
  #ifdef _PTHREAD_USE_MANGLED_NAMES_
	#define pthread_self __pthread_self
  #endif /* Name mangling */
  extern pthread_t pthread_self( void );
#endif /* OSF1 pthread_self function prototyping bug */

/* The pthreads implementation on MP-RAS (NCR User Space Threads based on
   CMA threads for DCE) doesn't accept NULL for several of the attribute
   arguments so we have to supply pthread_mutexattr_default attributes */

#ifdef _MPRAS
  #undef MUTEX_INIT
  #define MUTEX_INIT( mutex )	pthread_mutex_init( mutex, \
													pthread_mutexattr_default )
  #undef THREAD_CREATE
  #define THREAD_CREATE( function, arg, handle ) \
								( pthread_create( &handle, pthread_attr_default, \
												  function, arg ) ? CRYPT_ERROR : CRYPT_OK )
#endif /* _MPRAS */

/* Some systems (notable MVS and MP-RAS) use non-scalar pthread_t's, so we
   have to handle initialisation of these specially */

#if defined( __MVS__ ) || defined( _MPRAS )
  #undef THREAD_INITIALISER
  #define THREAD_INITIALISER	{ 0 }
#endif /* Non-scalar pthread_t's */

/* UnixWare/SCO uses a default thread stack size so tiny that almost nothing
   can run with it, so we have to use a custom thread-creation function that
   sets the stack size to something reasonable */

#ifdef __SCO_VERSION__
  #undef THREAD_CREATE
  #define THREAD_CREATE( function, arg, handle ) \
		  createThread( function, arg, &handle )

  int createThread( void *( *function )( void * ), void *arg, pthread_t *handle );
#endif /* UnixWare/SCO */

/* Some variables are protected by locks.  Before we can read or write these
   variables in a multithreaded environment we need to lock them so that they
   can't be accessed or modified by other threads while we're using them.
   The following macros provide this locking capability.

   In some very unusual cases (see the initialistion handling code for
   details) it's possible that an attempt might be made to lock a mutex
   before it's been initialised (this can only happen due to a programming
   error by the caller, unfortunately it can't always be caught reliably).
   Setting the mutex to { 0 } is, in most threading implementations,
   equivalent to initialising it normally, so we do this to catch most
   occurences of the problem.

   Due to the complexity of the locking process using pthreads' non-reentrant
   mutexes, we don't try and lock+unlock the mutex before we destroy it.
   This isn't a major issue since it's just a safety precaution, the kernel
   should have forced any remaining threads to exit by the time the shutdown
   occurs anyway */

#define DECLARE_LOCKING_VARS( name ) \
		static MUTEX name##Mutex = { 0 }; \
		static BOOLEAN name##MutexInitialised = FALSE; \
		static THREAD name##MutexOwner; \
		static int name##MutexLockcount = 0;
#define initResourceLock( name ) \
		if( !name##MutexInitialised ) \
			{ \
			MUTEX_INIT( &name##Mutex ); \
			name##MutexInitialised = TRUE; \
			}
#define deleteResourceLock( name ) \
		if( name##MutexInitialised ) \
			{ \
			MUTEX_DESTROY( &name##Mutex ); \
			name##MutexInitialised = FALSE; \
			}
#define lockResource( name ) \
		if( MUTEX_TRYLOCK( &name##Mutex ) ) \
			{ \
			if( !THREAD_SAME( name##MutexOwner, THREAD_SELF() ) ) \
				MUTEX_LOCK( &name##Mutex ); \
			else \
				name##MutexLockcount++; \
			} \
		name##MutexOwner = THREAD_SELF();
#define unlockResource( name ) \
		if( name##MutexLockcount > 0 ) \
			name##MutexLockcount--; \
		else \
			MUTEX_UNLOCK( &name##Mutex );

#elif defined( __BEOS__ )

#include <kernel/OS.h>

/* Handles to threads and system synchronisation objects */

#define THREAD_HANDLE			THREAD
#define SEMAPHORE_HANDLE		THREAD

/* Define a thread function */

#define THREADFUNC_DEFINE( name, arg )	thread_id name( void *arg )

/* Thead management functions.  The re-entrancy of BeOS semaphores is
   unclear, if they aren't re-entrant it would be necessary to emulate them
   as for Posix threads

   BeOS threads are created in the suspended state, so after we create the
   thread we have to resume it to start it running */

#define MUTEX					sem_id
#define MUTEX_INIT( mutex )		mutex = create_sem( 1, NULL )
#define MUTEX_DESTROY			delete_sem
#define MUTEX_LOCK				acquire_sem
#define MUTEX_TRYLOCK( mutex)	( acquire_sem_etc( mutex, 1, \
												   B_RELATIVE_TIMEOUT, 0 ) == B_WOULD_BLOCK )
#define MUTEX_UNLOCK			release_sem

#define THREAD					thread_id
#define THREAD_CREATE( function, arg, handle ) \
								( ( handle = \
										spawn_thread( function, NULL, \
													  B_NORMAL_PRIORITY, arg ) ) < B_NO_ERROR ? \
									CRYPT_ERROR : \
									resume_thread( handle ) )
#define THREAD_EXIT()			exit_thread( 0 )
#define THREAD_CREATE_VARS
#define THREAD_INITIALISER		0
#define THREAD_SAME( thread1, thread2 ) \
								( ( thread1 ) == ( thread2 ) )
#define THREAD_SELF()			find_thread( NULL )
#define THREAD_SLEEP( ms )		snooze( ms )
#define THREAD_YIELD()			snooze( estimate_max_scheduling_latency( -1 ) + 1 )
#define THREAD_WAIT( thread )	{ \
								status_t dummy; \
								\
								wait_for_thread( thread, &dummy ); \
								}
#define THREAD_CLOSE( thread )

/* Some variables are protected by locks.  Before we can read or write these
   variables in a multithreaded environment we need to lock them so they
   can't be accessed or modified by other threads while we're using them.
   The following macros provide this locking capability.

   In some very unusual cases (see the initialistion handling code for
   details) it's possible that an attempt might be made to lock a mutex
   before it's been initialised (this can only happen due to a programming
   error by the caller, unfortunately it can't always be caught reliably).
   Setting the mutex to { 0 } is, in most threading implementations,
   equivalent to initialising it normally, so we do this to catch most
   occurences of the problem */

#define DECLARE_LOCKING_VARS( name ) \
		static MUTEX name##Mutex = { 0 }; \
		static BOOLEAN name##MutexInitialised = FALSE; \
		static THREAD name##MutexOwner; \
		static int name##MutexLockcount = 0;
#define initResourceLock( name ) \
		if( !name##MutexInitialised ) \
			{ \
			MUTEX_INIT( name##Mutex ); \
			name##MutexInitialised = TRUE; \
			}
#define deleteResourceLock( name ) \
		if( name##MutexInitialised ) \
			{ \
			MUTEX_LOCK( name##Mutex ); \
			MUTEX_UNLOCK( name##Mutex ); \
			MUTEX_DESTROY( name##Mutex ); \
			name##MutexInitialised = FALSE; \
			}
#define lockResource( name ) \
		if( MUTEX_TRYLOCK( name##Mutex ) ) \
			{ \
			if( !THREAD_SAME( name##MutexOwner, THREAD_SELF() ) ) \
				MUTEX_LOCK( name##Mutex ); \
			else \
				name##MutexLockcount++; \
			} \
		name##MutexOwner = THREAD_SELF();
#define unlockResource( name ) \
		if( name##MutexLockcount > 0 ) \
			name##MutexLockcount--; \
		else \
			MUTEX_UNLOCK( name##Mutex );

/* Remember that we're using threaded functions */

#define USE_THREADS

#elif defined( __IBM4758__ )

#include <cpqlib.h>

/* Some variables are protected by locks.  Before we can read or write these
   variables in a multithreaded environment we need to lock them so they
   can't be accessed or modified by other threads while we're using them.
   The following macros provide this locking capability */

#define DECLARE_LOCKING_VARS( name ) \
		static long name##Semaphore; \
		static BOOLEAN name##SemaphoreInitialised = FALSE;
#define initResourceLock( name ) \
		if( !name##SemaphoreInitialised ) \
			{ \
			CPCreateSerSem( NULL, 0, 0, &name##Semaphore ); \
			name##SemaphoreInitialised = TRUE; \
			}
#define deleteResourceLock( name ) \
		if( name##SemaphoreInitialised ) \
			{ \
			CPSemClaim( name##Semaphore, SVCWAITFOREVER ); \
			CPSemRelease( name##Semaphore ); \
			CPDelete( name##Semaphore, 0 ); \
			name##SemaphoreInitialised = FALSE; \
			}
#define lockResource( name ) \
		CPSemClaim( name##Semaphore, SVCWAITFOREVER )
#define unlockResource( name ) \
		CPSemRelease( name##Semaphore )

/* Some objects are owned by one thread (called a task in CP/Q) and can't
   be accessed by any other threads.  The following macros provide facilities
   to declare the thread ID variables and check that the current thread is
   allowed to access this object.

   Since the 4758 access control model differs somewhat from the standard one,
   this facility isn't currently used */

/* Define a thread function:  CP/Q tasks function in a somewhat peculiar
   manner, this facility isn't currently used */

#endif /* OS-specific object locking and ownership handling */

/* Generic or NOP versions of functions and types declared for those OS's
   that don't support extended functionality.  The DECLARE_xxx macros are
   expanded into dummy variable declarations to avoid problems with zero-
   size entries in cases where they're the only element in a struct or
   incomplete declarations where they're preceded by the static keyword or
   various other, similar situations.  In addition for the (global) locking
   variable names we append the actual name to prevent name space
   collisions */

#ifndef USE_THREADS
  #define DECLARE_LOCKING_VARS( name )			int dummy##name;
  #define initResourceLock( name )
  #define deleteResourceLock( name )
  #define lockResource( name )
  #define unlockResource( name )

  #define THREAD_HANDLE							int
  #define SEMAPHORE_HANDLE						int
  #define THREAD_INITIALISER					0
  #define THREAD_SELF()							0
  #define THREAD_SAME( thread1, thread2 )		TRUE
  #define THREAD_YIELD()
  #define THREAD_WAIT( thread )
  #define THREAD_CLOSE( thread )
#endif /* Resource ownership macros */

/****************************************************************************
*																			*
*							Misc.OS-specific Functions						*
*																			*
****************************************************************************/

/* WinNT and its derivatives support ACL-based access control mechanisms for
   system objects (modulo a great many holes), the following functions return
   the security info needed to restrict access to owner-only when creating an
   object */

#ifdef __WIN32__
void *initACLInfo( const int access );
void *getACLInfo( void *securityInfoPtr );
void freeACLInfo( void *securityInfoPtr );
#endif /* __WIN32__ */

#endif /* _CRYPTOS_DEFINED */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -