Fixed many warnings
[sdk] / ecere / src / sys / Thread.ec
1 namespace sys;
2
3 #define set _set
4 #define uint _uint
5 // Platform includes
6 #if defined(__WIN32__)
7 #define WIN32_LEAN_AND_MEAN
8 #define String String_
9 #define Thread Thread_
10 #include <windows.h>
11 #undef String
12 #undef Thread
13 #else
14 #include <pthread.h>
15 #ifndef __ANDROID__
16 #include <signal.h>
17 #endif
18 #endif
19 #undef uint
20 #undef set
21
22 import "instance"
23
24 #if !defined(__WIN32__)
25 import "Semaphore"
26 #endif
27
28 public enum ThreadPriority
29 {
30    normal = 0,
31    aboveNormal = 1,
32    belowNormal = -1,
33    highest = 2,
34    lowest = -2,
35    idle = -15,
36    timeCritical = 15
37 };
38
39 public class Thread
40 {
41    ~Thread()
42    {
43 #if defined(__WIN32__)
44       if(handle)
45          CloseHandle(handle);
46 #endif
47    }
48
49 #if defined(__WIN32__)
50    HANDLE handle;
51    uint id;
52 #else
53    pthread_t id;
54    bool dontDetach;
55    Semaphore sem { };
56 #endif
57
58    uint returnCode;
59    bool started;
60
61 #if defined(__WIN32__)
62    uint ThreadCallBack()
63 #else
64    void * ThreadCallBack()
65 #endif
66    {
67       uint returnCode = this.returnCode = Main();
68       started = false;
69 #if defined(__WIN32__)
70       CloseHandle(handle);
71       handle = null;
72 #else
73       if(!dontDetach)
74          pthread_detach(id);
75       sem.Release();
76
77 #endif
78       delete this;
79 #if defined(__WIN32__)
80       return returnCode;
81 #else
82       return (void *)returnCode;
83 #endif
84    }
85
86 public:
87    virtual uint Main(void);
88
89    void Create()
90    {
91       incref this;
92       if(!started)
93       {
94 #if !defined(__WIN32__)
95          sem.TryWait();
96 #endif
97          started = true;
98          // printf("Creating %s thread\n", _class.name);
99 #if defined(__WIN32__)
100          if(!handle)
101          {
102             DWORD tID;
103             handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadCallBack, this, 0, &tID);
104             id = (uint)tID;
105          }
106 #else
107          {
108             int error;
109             /*pthread_attr_t attr;
110             pthread_attr_init(&attr);
111             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);*/  // Default attribute ???
112             error = pthread_create(&id, null /*&attr*/, ThreadCallBack, this);
113             if(error)
114                printf("Error %d creating a thread\n", error);
115           }
116 #endif
117       }
118    }
119
120    void Kill()
121    {
122 #if defined(__WIN32__)
123       if(handle)
124       {
125          TerminateThread(handle, 0);
126          handle = null;
127       }
128 #else
129       if(started)
130          pthread_kill(id, SIGQUIT);
131 #endif
132       if(started)
133       {
134          started = false;
135          delete this;
136       }
137    }
138
139    void Wait()
140    {
141 #if defined(__WIN32__)
142       if(WaitForSingleObject(handle, INFINITE /*2000*/) == WAIT_TIMEOUT)
143          PrintLn("Thread not returning?\n");
144 #else
145
146       /*dontDetach = true;
147       if(started)
148          pthread_join(id, NULL);*/
149
150       if(started)
151          sem.Wait();
152 #endif
153    }
154
155    void SetPriority(ThreadPriority priority)
156    {
157 #if defined(__WIN32__)
158       SetThreadPriority(handle, priority);
159 #else
160       /*
161       struct sched_param param;
162       int policy = (priority > 0) ? SCHED_RR : SCHED_OTHER;
163       param.sched_priority = (priority > 0) ? (priority * 99 / 15) : 0;
164       pthread_setschedparam(id, policy, &param);
165       */
166 #endif
167    }
168
169    property bool created { get { return started; } };
170 }