00001 #include <string.h> 00002 #ifdef _WIN32 00003 #include <windows.h> 00004 #else 00005 #include <pthread.h> 00006 #endif 00007 00008 #include "data.h" 00009 #include "code.h" 00010 00011 static void lockDestroy(void* lock) { naFreeLock(lock); } 00012 static naGhostType LockType = { lockDestroy }; 00013 00014 static void semDestroy(void* sem) { naFreeSem(sem); } 00015 static naGhostType SemType = { semDestroy }; 00016 00017 typedef struct { 00018 naContext ctx; 00019 naRef func; 00020 } ThreadData; 00021 00022 #ifdef _WIN32 00023 static DWORD WINAPI threadtop(LPVOID param) 00024 #else 00025 static void* threadtop(void* param) 00026 #endif 00027 { 00028 ThreadData* td = param; 00029 naCall(td->ctx, td->func, 0, 0, naNil(), naNil()); 00030 naFreeContext(td->ctx); 00031 naFree(td); 00032 return 0; 00033 } 00034 00035 static naRef f_newthread(naContext c, naRef me, int argc, naRef* args) 00036 { 00037 ThreadData *td; 00038 if(argc < 1 || !naIsFunc(args[0])) 00039 naRuntimeError(c, "bad/missing argument to newthread"); 00040 td = naAlloc(sizeof(*td)); 00041 td->ctx = naNewContext(); 00042 td->func = args[0]; 00043 naTempSave(td->ctx, td->func); 00044 #ifdef _WIN32 00045 CreateThread(0, 0, threadtop, td, 0, 0); 00046 #else 00047 { 00048 pthread_t t; int err; 00049 if((err = pthread_create(&t, 0, threadtop, td))) 00050 naRuntimeError(c, "newthread failed: %s", strerror(err)); 00051 pthread_detach(t); 00052 } 00053 #endif 00054 return naNil(); 00055 } 00056 00057 static naRef f_newlock(naContext c, naRef me, int argc, naRef* args) 00058 { 00059 return naNewGhost(c, &LockType, naNewLock()); 00060 } 00061 00062 static naRef f_lock(naContext c, naRef me, int argc, naRef* args) 00063 { 00064 if(argc > 0 && naGhost_type(args[0]) == &LockType) { 00065 naModUnlock(); 00066 naLock(naGhost_ptr(args[0])); 00067 naModLock(); 00068 } 00069 return naNil(); 00070 } 00071 00072 static naRef f_unlock(naContext c, naRef me, int argc, naRef* args) 00073 { 00074 if(argc > 0 && naGhost_type(args[0]) == &LockType) 00075 naUnlock(naGhost_ptr(args[0])); 00076 return naNil(); 00077 } 00078 00079 static naRef f_newsem(naContext c, naRef me, int argc, naRef* args) 00080 { 00081 return naNewGhost(c, &SemType, naNewSem()); 00082 } 00083 00084 static naRef f_semdown(naContext c, naRef me, int argc, naRef* args) 00085 { 00086 if(argc > 0 && naGhost_type(args[0]) == &SemType) { 00087 naModUnlock(); 00088 naSemDown(naGhost_ptr(args[0])); 00089 naModLock(); 00090 } 00091 return naNil(); 00092 } 00093 00094 static naRef f_semup(naContext c, naRef me, int argc, naRef* args) 00095 { 00096 if(argc > 0 && naGhost_type(args[0]) == &SemType) 00097 naSemUp(naGhost_ptr(args[0]), 1); 00098 return naNil(); 00099 } 00100 00101 static naCFuncItem funcs[] = { 00102 { "newthread", f_newthread }, 00103 { "newlock", f_newlock }, 00104 { "lock", f_lock }, 00105 { "unlock", f_unlock }, 00106 { "newsem", f_newsem }, 00107 { "semdown", f_semdown }, 00108 { "semup", f_semup }, 00109 { 0 } 00110 }; 00111 00112 naRef naInit_thread(naContext c) 00113 { 00114 return naGenLib(c, funcs); 00115 }