/* * Copyright © 2001 Novell, Inc. All Rights Reserved. * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ /* * FILENAME : nw5thread.h * DESCRIPTION : Thread related functions. * Author : SGP * Date : January 2001. * */ #ifndef _NW5THREAD_H #define _NW5THREAD_H #include #include "netware.h" typedef long perl_key; // The line below is just a definition to avoid compilation error. // It is not being used anywhere. // Ananth, 3 Sept 2001 typedef struct nw_cond { long waiters; unsigned int sem; } perl_cond; #if defined (USE_ITHREADS) && defined(MPK_ON) #ifdef __cplusplus extern "C" { #endif #include #include #define kSUCCESS (0) #define ERROR_INVALID_MUTEX (0x1010) #ifdef __cplusplus } #endif #undef WORD //On NetWare, since the NLM will be resident, only once the MUTEX_INIT gets called and //this will be freed when the script terminates. But when a new script is executed, //then MUTEX_LOCK will fail since it is already freed. Even if this problem is fixed //by not freeing the mutex when script terminates but when the NLM unloads, there will //still be problems when multiple scripts are running simultaneously in a multi-processor //machine - sgp typedef MUTEX perl_mutex; # define MUTEX_INIT(m) \ STMT_START { \ /*if ((*(m) = kMutexAlloc("NetWarePerlMutex")) == NULL) */\ /*Perl_croak_nocontext("panic: MUTEX_ALLOC"); */\ /*ConsolePrintf("Mutex Init %d\n",*(m)); */\ } STMT_END # define MUTEX_LOCK(m) \ STMT_START { \ /*ConsolePrintf("Mutex lock %d\n",*(m)); */\ /*if (kMutexLock(*(m)) == ERROR_INVALID_MUTEX) */\ /*Perl_croak_nocontext("panic: MUTEX_LOCK"); */\ } STMT_END # define MUTEX_UNLOCK(m) \ STMT_START { \ /*ConsolePrintf("Mutex unlock %d\n",*(m)); */\ /*if (kMutexUnlock(*(m)) != kSUCCESS) \ Perl_croak_nocontext("panic: MUTEX_UNLOCK"); */\ } STMT_END # define MUTEX_DESTROY(m) \ STMT_START { \ /*ConsolePrintf("Mutex Destroy %d\n",*(m)); */\ /*if (kMutexWaitCount(*(m)) == 0 ) */\ /*{ */\ /*PERL_SET_INTERP(NULL); *//*newly added CHKSGP???*/ \ /*if (kMutexFree(*(m)) != kSUCCESS) */ \ /*Perl_croak_nocontext("panic: MUTEX_FREE"); */\ /*} */\ } STMT_END #else typedef unsigned long perl_mutex; # define MUTEX_INIT(m) # define MUTEX_LOCK(m) # define MUTEX_UNLOCK(m) # define MUTEX_DESTROY(m) #endif /* These macros assume that the mutex associated with the condition * will always be held before COND_{SIGNAL,BROADCAST,WAIT,DESTROY}, * so there's no separate mutex protecting access to (c)->waiters */ //For now let us just see when this happens -sgp. #define COND_INIT(c) \ STMT_START { \ /*ConsolePrintf("In COND_INIT\n"); */\ } STMT_END /* (c)->waiters = 0; \ (c)->sem = OpenLocalSemaphore (0); \ if ((c)->sem == NULL) \ Perl_croak_nocontext("panic: COND_INIT (%ld)",errno); \*/ #define COND_SIGNAL(c) \ STMT_START { \ /*ConsolePrintf("In COND_SIGNAL\n"); */\ } STMT_END /*if ((c)->waiters > 0 && \ SignalLocalSemaphore((c)->sem) != 0) \ Perl_croak_nocontext("panic: COND_SIGNAL (%ld)",errno); \*/ #define COND_BROADCAST(c) \ STMT_START { \ /*ConsolePrintf("In COND_BROADCAST\n"); */\ } STMT_END /*if ((c)->waiters > 0 ) { \ int count; \ for(count=0; count<(c)->waiters; count++) { \ if(SignalLocalSemaphore((c)->sem) != 0) \ Perl_croak_nocontext("panic: COND_BROADCAST (%ld)",GetLastError());\ } \ } \*/ #define COND_WAIT(c, m) \ STMT_START { \ /*ConsolePrintf("In COND_WAIT\n"); */\ } STMT_END #define COND_DESTROY(c) \ STMT_START { \ /*ConsolePrintf("In COND_DESTROY\n"); */\ } STMT_END /* (c)->waiters = 0; \ if (CloseLocalSemaphore((c)->sem) != 0) \ Perl_croak_nocontext("panic: COND_DESTROY (%ld)",errno); \*/ #if 0 #define DETACH(t) \ STMT_START { \ if (CloseHandle((t)->self) == 0) { \ MUTEX_UNLOCK(&(t)->mutex); \ Perl_croak_nocontext("panic: DETACH"); \ } \ } STMT_END #endif //#if 0 //Following has to be defined CHKSGP #if defined(PERLDLL) && defined(USE_DECLSPEC_THREAD) extern __declspec(thread) void *PL_current_context; #define PERL_SET_CONTEXT(t) (PL_current_context = t) #define PERL_GET_CONTEXT PL_current_context #else #define PERL_GET_CONTEXT Perl_get_context() #define PERL_SET_CONTEXT(t) Perl_set_context(t) #endif //Check the following, will be used in Thread extension - CHKSGP #define THREAD_RET_TYPE unsigned __stdcall #define INIT_THREADS NOOP //Ideally this should have been PL_thr_key = fnInitializeThreadCtx(); //See the comment at the end of file nw5thread.c as to why PL_thr_key is not assigned - sgp #define ALLOC_THREAD_KEY \ STMT_START { \ fnInitializeThreadCtx(); \ } STMT_END #endif /* _NW5THREAD_H */