Skip to content

Commit 4da005b

Browse files
author
Aidan Lee
committed
have old c-style functions use new implementation
1 parent dcfbf23 commit 4da005b

1 file changed

Lines changed: 9 additions & 250 deletions

File tree

src/hx/Thread.cpp

Lines changed: 9 additions & 250 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,9 @@
55
#include <hx/thread/ConditionVariable.hpp>
66
#include <hx/thread/RecursiveMutex.hpp>
77
#include <hx/thread/CountingSemaphore.hpp>
8+
#include "thread/ThreadImpl.hpp"
89
#include <atomic>
910

10-
DECLARE_TLS_DATA(class hxThreadInfo, tlsCurrentThread);
11-
12-
// Thread number 0 is reserved for the main thread
13-
static std::atomic_int g_nextThreadNumber(1);
14-
15-
16-
// How to manage hxThreadInfo references for non haxe threads (main, extenal)?
17-
// HXCPP_THREAD_INFO_PTHREAD - use pthread api
18-
// HXCPP_THREAD_INFO_LOCAL - use thread_local storage
19-
// HXCPP_THREAD_INFO_SINGLETON - use one structure for all threads. Not ideal.
20-
21-
#if __cplusplus > 199711L && !defined(__BORLANDC__)
22-
#define HXCPP_THREAD_INFO_LOCAL
23-
#elif defined (HXCPP_PTHREADS)
24-
#define HXCPP_THREAD_INFO_PTHREAD
25-
#else
26-
#define HXCPP_THREAD_INFO_SINGLETON
27-
#endif
28-
29-
3011
// --- Deque ----------------------------------------------------------
3112

3213
struct Deque : public Array_obj<Dynamic>
@@ -171,265 +152,49 @@ Dynamic __hxcpp_deque_pop(Dynamic q,bool block)
171152
return d->PopFront(block);
172153
}
173154

174-
175-
176155
// --- Thread ----------------------------------------------------------
177156

178-
class hxThreadInfo : public hx::Object
179-
{
180-
public:
181-
typedef
182-
#if (HXCPP_API_LEVEL>=500)
183-
hx::Callable<void()>
184-
#else
185-
Dynamic
186-
#endif
187-
ThreadFuncType;
188-
189-
HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdThreadInfo };
190-
191-
hxThreadInfo(ThreadFuncType inFunction, int inThreadNumber)
192-
: mFunction(inFunction), mThreadNumber(inThreadNumber), mTLS(0,0)
193-
{
194-
mSemaphore = new HxSemaphore;
195-
mDeque = Deque::Create();
196-
HX_OBJ_WB_NEW_MARKED_OBJECT(this);
197-
}
198-
hxThreadInfo()
199-
{
200-
mSemaphore = 0;
201-
mDeque = Deque::Create();
202-
HX_OBJ_WB_NEW_MARKED_OBJECT(this);
203-
}
204-
int GetThreadNumber() const
205-
{
206-
return mThreadNumber;
207-
}
208-
void CleanSemaphore()
209-
{
210-
delete mSemaphore;
211-
mSemaphore = 0;
212-
}
213-
void Send(Dynamic inMessage)
214-
{
215-
mDeque->PushBack(inMessage);
216-
}
217-
Dynamic ReadMessage(bool inBlocked)
218-
{
219-
return mDeque->PopFront(inBlocked);
220-
}
221-
String toString()
222-
{
223-
return String(GetThreadNumber());
224-
}
225-
void SetTLS(int inID,Dynamic inVal) {
226-
mTLS->__SetItem(inID,inVal);
227-
}
228-
Dynamic GetTLS(int inID) { return mTLS[inID]; }
229-
230-
void __Mark(hx::MarkContext *__inCtx)
231-
{
232-
HX_MARK_MEMBER(mFunction);
233-
HX_MARK_MEMBER(mTLS);
234-
if (mDeque)
235-
HX_MARK_OBJECT(mDeque);
236-
}
237-
#ifdef HXCPP_VISIT_ALLOCS
238-
void __Visit(hx::VisitContext *__inCtx)
239-
{
240-
HX_VISIT_MEMBER(mFunction);
241-
HX_VISIT_MEMBER(mTLS);
242-
if (mDeque)
243-
HX_VISIT_OBJECT(mDeque);
244-
}
245-
#endif
246-
247-
248-
Array<Dynamic> mTLS;
249-
HxSemaphore *mSemaphore;
250-
ThreadFuncType mFunction;
251-
int mThreadNumber;
252-
Deque *mDeque;
253-
};
254-
255-
256-
THREAD_FUNC_TYPE hxThreadFunc( void *inInfo )
257-
{
258-
// info[1] will the the "top of stack" - values under this
259-
// (ie info[0] and other stack values) will be in the GC conservative range
260-
hxThreadInfo *info[2];
261-
info[0] = (hxThreadInfo *)inInfo;
262-
info[1] = 0;
263-
264-
tlsCurrentThread = info[0];
265-
266-
hx::SetTopOfStack((int *)&info[1], true);
267-
268-
// Release the creation function
269-
info[0]->mSemaphore->Set();
270-
271-
// Call the debugger function to annouce that a thread has been created
272-
//__hxcpp_dbg_threadCreatedOrTerminated(info[0]->GetThreadNumber(), true);
273-
274-
if ( info[0]->mFunction.GetPtr() )
275-
{
276-
// Try ... catch
277-
info[0]->mFunction();
278-
}
279-
280-
// Call the debugger function to annouce that a thread has terminated
281-
//__hxcpp_dbg_threadCreatedOrTerminated(info[0]->GetThreadNumber(), false);
282-
283-
hx::UnregisterCurrentThread();
284-
285-
tlsCurrentThread = 0;
286-
287-
THREAD_FUNC_RET
288-
}
289-
290-
291157
#if (HXCPP_API_LEVEL>=500)
292158
Dynamic __hxcpp_thread_create(hx::Callable<void()> inStart)
293159
#else
294160
Dynamic __hxcpp_thread_create(Dynamic inStart)
295161
#endif
296162
{
297-
#ifdef EMSCRIPTEN
298-
return hx::Throw( HX_CSTRING("Threads are not supported on Emscripten") );
299-
#else
300-
int threadNumber = g_nextThreadNumber++;
301-
302-
hxThreadInfo *info = new hxThreadInfo(inStart, threadNumber);
303-
304-
hx::GCPrepareMultiThreaded();
305-
hx::EnterGCFreeZone();
306-
307-
bool ok = HxCreateDetachedThread(hxThreadFunc, info);
308-
if (ok)
309-
{
310-
info->mSemaphore->Wait();
311-
}
312-
313-
hx::ExitGCFreeZone();
314-
info->CleanSemaphore();
315-
316-
if (!ok)
317-
throw Dynamic( HX_CSTRING("Could not create thread") );
318-
return info;
319-
#endif
320-
}
321-
322-
#ifdef HXCPP_THREAD_INFO_PTHREAD
323-
static pthread_key_t externThreadInfoKey;;
324-
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
325-
static void destroyThreadInfo(void *i)
326-
{
327-
hx::Object **threadRoot = (hx::Object **)i;
328-
hx::GCRemoveRoot(threadRoot);
329-
delete threadRoot;
330-
}
331-
static void make_key()
332-
{
333-
pthread_key_create(&externThreadInfoKey, destroyThreadInfo);
334-
}
335-
#elif defined(HXCPP_THREAD_INFO_LOCAL)
336-
struct ThreadInfoHolder
337-
{
338-
hx::Object **threadRoot;
339-
ThreadInfoHolder() : threadRoot(0) { }
340-
~ThreadInfoHolder()
341-
{
342-
if (threadRoot)
343-
{
344-
hx::GCRemoveRoot(threadRoot);
345-
delete threadRoot;
346-
}
347-
}
348-
void set(hx::Object **info) { threadRoot = info; }
349-
hxThreadInfo *get() { return threadRoot ? (hxThreadInfo *)*threadRoot : nullptr; }
350-
351-
};
352-
static thread_local ThreadInfoHolder threadHolder;
353-
#else
354-
static hx::Object **sMainThreadInfoRoot = 0;
355-
#endif
356-
357-
static hxThreadInfo *GetCurrentInfo(bool createNew = true)
358-
{
359-
hxThreadInfo *info = tlsCurrentThread;
360-
if (!info)
361-
{
362-
#ifdef HXCPP_THREAD_INFO_PTHREAD
363-
pthread_once(&key_once, make_key);
364-
hxThreadInfo **pp = (hxThreadInfo **)pthread_getspecific(externThreadInfoKey);
365-
if (pp)
366-
info = *pp;
367-
#elif defined(HXCPP_THREAD_INFO_LOCAL)
368-
info = threadHolder.get();
369-
#else
370-
if (sMainThreadInfoRoot)
371-
info = (hxThreadInfo *)*sMainThreadInfoRoot;
372-
#endif
373-
}
374-
375-
if (!info && createNew)
376-
{
377-
// New, non-haxe thread - might be the first thread, or might be a new
378-
// foreign thread.
379-
info = new hxThreadInfo(null(), 0);
380-
hx::Object **threadRoot = new hx::Object *;
381-
*threadRoot = info;
382-
hx::GCAddRoot(threadRoot);
383-
#ifdef HXCPP_THREAD_INFO_PTHREAD
384-
pthread_setspecific(externThreadInfoKey, threadRoot);
385-
#elif defined(HXCPP_THREAD_INFO_LOCAL)
386-
threadHolder.set(threadRoot);
387-
#else
388-
sMainThreadInfoRoot = threadRoot;
389-
#endif
390-
}
391-
return info;
163+
return hx::thread::Thread_obj::create(inStart);
392164
}
393165

394166
Dynamic __hxcpp_thread_current()
395167
{
396-
return GetCurrentInfo();
168+
return hx::thread::Thread_obj::current();
397169
}
398170

399171
void __hxcpp_thread_send(Dynamic inThread, Dynamic inMessage)
400172
{
401-
hxThreadInfo *info = dynamic_cast<hxThreadInfo *>(inThread.mPtr);
402-
if (!info)
403-
throw HX_INVALID_OBJECT;
404-
info->Send(inMessage);
173+
hx::Throw(HX_CSTRING("Not Implemented"));
405174
}
406175

407176
Dynamic __hxcpp_thread_read_message(bool inBlocked)
408177
{
409-
hxThreadInfo *info = GetCurrentInfo();
410-
return info->ReadMessage(inBlocked);
178+
return hx::Throw(HX_CSTRING("Not Implemented"));
411179
}
412180

413181
bool __hxcpp_is_current_thread(hx::Object *inThread)
414182
{
415-
hxThreadInfo *info = tlsCurrentThread;
416-
return info==inThread;
183+
return inThread == hx::thread::Thread_obj::current();
417184
}
418185

419186
// --- TLS ------------------------------------------------------------
420187

421188
Dynamic __hxcpp_tls_get(int inID)
422189
{
423-
return GetCurrentInfo()->GetTLS(inID);
190+
return reinterpret_cast<hx::thread::ThreadImpl_obj*>(hx::thread::Thread_obj::current().GetPtr())->getSlot(inID);
424191
}
425192

426193
void __hxcpp_tls_set(int inID,Dynamic inVal)
427194
{
428-
GetCurrentInfo()->SetTLS(inID,inVal);
195+
reinterpret_cast<hx::thread::ThreadImpl_obj*>(hx::thread::Thread_obj::current().GetPtr())->setSlot(inID, inVal);
429196
}
430197

431-
432-
433198
// --- Mutex ------------------------------------------------------------
434199

435200
Dynamic __hxcpp_mutex_create()
@@ -636,13 +401,7 @@ void __hxcpp_lock_release(Dynamic inlock)
636401

637402
int __hxcpp_GetCurrentThreadNumber()
638403
{
639-
// Can't allow GetCurrentInfo() to create the main thread's info
640-
// because that can cause a call loop.
641-
hxThreadInfo *threadInfo = GetCurrentInfo(false);
642-
if (!threadInfo) {
643-
return 0;
644-
}
645-
return threadInfo->GetThreadNumber();
404+
return hx::thread::Thread_obj::id();
646405
}
647406

648407
// --- Atomic ---

0 commit comments

Comments
 (0)