]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/threadlib.c
Removal of PLIB/SG from SimGear
[simgear.git] / simgear / nasal / threadlib.c
1 #include <string.h>
2 #ifdef _WIN32
3 #include <windows.h>
4 #else
5 #include <pthread.h>
6 #endif
7
8 #include "data.h"
9 #include "code.h"
10
11 static void lockDestroy(void* lock) { naFreeLock(lock); }
12 static naGhostType LockType = { lockDestroy };
13
14 static void semDestroy(void* sem) { naFreeSem(sem); }
15 static naGhostType SemType = { semDestroy };
16
17 typedef struct {
18     naContext ctx;
19     naRef func;
20 } ThreadData;
21
22 #ifdef _WIN32
23 static DWORD WINAPI threadtop(LPVOID param)
24 #else
25 static void* threadtop(void* param)
26 #endif
27 {
28     ThreadData* td = param;
29     naCall(td->ctx, td->func, 0, 0, naNil(), naNil());
30     naFreeContext(td->ctx);
31     naFree(td);
32     return 0;
33 }
34
35 static naRef f_newthread(naContext c, naRef me, int argc, naRef* args)
36 {
37     ThreadData *td;
38     if(argc < 1 || !naIsFunc(args[0]))
39         naRuntimeError(c, "bad/missing argument to newthread");
40     td = naAlloc(sizeof(*td));
41     td->ctx = naNewContext();
42     td->func = args[0];
43     naTempSave(td->ctx, td->func);
44 #ifdef _WIN32
45     CreateThread(0, 0, threadtop, td, 0, 0);
46 #else
47     {
48         pthread_t t; int err;
49         if((err = pthread_create(&t, 0, threadtop, td)))
50             naRuntimeError(c, "newthread failed: %s", strerror(err));
51         pthread_detach(t);
52     }
53 #endif
54     return naNil();
55 }
56
57 static naRef f_newlock(naContext c, naRef me, int argc, naRef* args)
58 {
59     return naNewGhost(c, &LockType, naNewLock());
60 }
61
62 static naRef f_lock(naContext c, naRef me, int argc, naRef* args)
63 {
64     if(argc > 0 && naGhost_type(args[0]) == &LockType) {
65         naModUnlock();
66         naLock(naGhost_ptr(args[0]));
67         naModLock();
68     }
69     return naNil();
70 }
71
72 static naRef f_unlock(naContext c, naRef me, int argc, naRef* args)
73 {
74     if(argc > 0 && naGhost_type(args[0]) == &LockType)
75         naUnlock(naGhost_ptr(args[0]));
76     return naNil();
77 }
78
79 static naRef f_newsem(naContext c, naRef me, int argc, naRef* args)
80 {
81     return naNewGhost(c, &SemType, naNewSem());
82 }
83
84 static naRef f_semdown(naContext c, naRef me, int argc, naRef* args)
85 {
86     if(argc > 0 && naGhost_type(args[0]) == &SemType) {
87         naModUnlock();
88         naSemDown(naGhost_ptr(args[0]));
89         naModLock();
90     }
91     return naNil();
92 }
93
94 static naRef f_semup(naContext c, naRef me, int argc, naRef* args)
95 {
96     if(argc > 0 && naGhost_type(args[0]) == &SemType)
97         naSemUp(naGhost_ptr(args[0]), 1);
98     return naNil();
99 }
100
101 static naCFuncItem funcs[] = {
102     { "newthread", f_newthread },
103     { "newlock", f_newlock },
104     { "lock", f_lock },
105     { "unlock", f_unlock },
106     { "newsem", f_newsem },
107     { "semdown", f_semdown },
108     { "semup", f_semup },
109     { 0 }
110 };
111
112 naRef naInit_thread(naContext c)
113 {
114     return naGenLib(c, funcs);
115 }