cleaned all trailing white space from source files.
[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    uint ThreadCallBack()
62    {
63       uint returnCode = this.returnCode = Main();
64       started = false;
65 #if defined(__WIN32__)
66       CloseHandle(handle);
67       handle = null;
68 #else
69       if(!dontDetach)
70          pthread_detach(id);
71       sem.Release();
72
73 #endif
74       delete this;
75       return returnCode;
76    }
77
78 public:
79    virtual uint Main(void);
80
81    void Create()
82    {
83       incref this;
84       if(!started)
85       {
86 #if !defined(__WIN32__)
87          sem.TryWait();
88 #endif
89          started = true;
90          // printf("Creating %s thread\n", _class.name);
91 #if defined(__WIN32__)
92          if(!handle)
93             handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadCallBack, this, 0, &id);
94 #else
95          {
96             int error;
97             /*pthread_attr_t attr;
98             pthread_attr_init(&attr);
99             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);*/  // Default attribute ???
100             error = pthread_create(&id, null /*&attr*/, (void *)ThreadCallBack, this);
101             if(error)
102                printf("Error %d creating a thread\n", error);
103           }
104 #endif
105       }
106    }
107
108    void Kill()
109    {
110 #if defined(__WIN32__)
111       if(handle)
112       {
113          TerminateThread(handle, 0);
114          handle = null;
115       }
116 #else
117       if(started)
118          pthread_kill(id, SIGQUIT);
119 #endif
120       if(started)
121       {
122          started = false;
123          delete this;
124       }
125    }
126
127    void Wait()
128    {
129 #if defined(__WIN32__)
130       if(WaitForSingleObject(handle, INFINITE /*2000*/) == WAIT_TIMEOUT)
131          PrintLn("Thread not returning?\n");
132 #else
133
134       /*dontDetach = true;
135       if(started)
136          pthread_join(id, NULL);*/
137
138       if(started)
139          sem.Wait();
140 #endif
141    }
142
143    void SetPriority(ThreadPriority priority)
144    {
145 #if defined(__WIN32__)
146       SetThreadPriority(handle, priority);
147 #else
148       /*
149       struct sched_param param;
150       int policy = (priority > 0) ? SCHED_RR : SCHED_OTHER;
151       param.sched_priority = (priority > 0) ? (priority * 99 / 15) : 0;
152       pthread_setschedparam(id, policy, &param);
153       */
154 #endif
155    }
156
157    property bool created { get { return started; } };
158 }