|
4 | 4 | #include <time.h> |
5 | 5 | #include <hx/thread/ConditionVariable.hpp> |
6 | 6 | #include <hx/thread/RecursiveMutex.hpp> |
| 7 | +#include <hx/thread/CountingSemaphore.hpp> |
7 | 8 | #include <atomic> |
8 | 9 |
|
9 | 10 | DECLARE_TLS_DATA(class hxThreadInfo, tlsCurrentThread); |
@@ -454,138 +455,29 @@ void __hxcpp_mutex_release(Dynamic inMutex) |
454 | 455 | mutex->release(); |
455 | 456 | } |
456 | 457 |
|
457 | | -#if defined(HX_LINUX) || defined(HX_ANDROID) |
458 | | -#define POSIX_SEMAPHORE |
459 | | -#include <semaphore.h> |
460 | | -#endif |
461 | | - |
462 | | -#if defined(HX_MACOS) || defined(IPHONE) || defined(APPLETV) |
463 | | -#define APPLE_SEMAPHORE |
464 | | -#include <dispatch/dispatch.h> |
465 | | -#endif |
466 | | - |
467 | | -class hxSemaphore : public hx::Object { |
468 | | -public: |
469 | | - hx::InternalFinalizer *mFinalizer; |
470 | | -#ifdef HX_WINDOWS |
471 | | - HANDLE sem; |
472 | | -#elif defined (POSIX_SEMAPHORE) |
473 | | - sem_t sem; |
474 | | -#elif defined(APPLE_SEMAPHORE) |
475 | | - dispatch_semaphore_t sem; |
476 | | -#endif |
477 | | - bool valid; |
478 | | - |
479 | | - hxSemaphore(int value) { |
480 | | - mFinalizer = new hx::InternalFinalizer(this); |
481 | | - mFinalizer->mFinalizer = clean; |
482 | | -#ifdef HX_WINDOWS |
483 | | - sem = CreateSemaphoreW(NULL, value, 0x7FFFFFFF, NULL); |
484 | | -#elif defined(POSIX_SEMAPHORE) |
485 | | - sem_init(&sem, 0, value); |
486 | | -#elif defined(APPLE_SEMAPHORE) |
487 | | - sem = dispatch_semaphore_create(value); |
488 | | -#endif |
489 | | - valid = true; |
490 | | - } |
491 | | - |
492 | | - HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdSemaphore }; |
493 | | - |
494 | | -#ifdef HXCPP_VISIT_ALLOCS |
495 | | - void __Visit(hx::VisitContext *__inCtx) { mFinalizer->Visit(__inCtx); } |
496 | | -#endif |
497 | | - |
498 | | - void Acquire() { |
499 | | - hx::EnterGCFreeZone(); |
500 | | -#if HX_WINDOWS |
501 | | - WaitForSingleObject(sem, INFINITE); |
502 | | -#elif defined(POSIX_SEMAPHORE) |
503 | | - sem_wait(&sem); |
504 | | -#elif defined(APPLE_SEMAPHORE) |
505 | | - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); |
506 | | -#endif |
507 | | - hx::ExitGCFreeZone(); |
508 | | - } |
509 | | - |
510 | | - bool TryAcquire(double timeout) { |
511 | | - hx::AutoGCFreeZone blocking; |
512 | | -#ifdef HX_WINDOWS |
513 | | - return WaitForSingleObject(sem, (DWORD)((FLOAT)timeout * 1000.0)) == 0; |
514 | | -#elif defined(POSIX_SEMAPHORE) |
515 | | - if (timeout == 0) { |
516 | | - return sem_trywait(&sem) == 0; |
517 | | - } else { |
518 | | - struct timeval tv; |
519 | | - struct timespec t; |
520 | | - double delta = timeout; |
521 | | - int idelta = (int)delta, idelta2; |
522 | | - delta -= idelta; |
523 | | - delta *= 1.0e9; |
524 | | - gettimeofday(&tv, NULL); |
525 | | - delta += tv.tv_usec * 1000.0; |
526 | | - idelta2 = (int)(delta / 1e9); |
527 | | - delta -= idelta2 * 1e9; |
528 | | - t.tv_sec = tv.tv_sec + idelta + idelta2; |
529 | | - t.tv_nsec = (long)delta; |
530 | | - return sem_timedwait(&sem, &t) == 0; |
531 | | - } |
532 | | -#elif defined(APPLE_SEMAPHORE) |
533 | | - return dispatch_semaphore_wait( |
534 | | - sem, |
535 | | - dispatch_time(DISPATCH_TIME_NOW, |
536 | | - (int64_t)(timeout * 1000 * 1000 * 1000))) == 0; |
537 | | -#else |
538 | | - return false; |
539 | | -#endif |
540 | | - } |
541 | | - |
542 | | - void Release() { |
543 | | -#if HX_WINDOWS |
544 | | - ReleaseSemaphore(sem, 1, NULL); |
545 | | -#elif defined(POSIX_SEMAPHORE) |
546 | | - sem_post(&sem); |
547 | | -#elif defined(APPLE_SEMAPHORE) |
548 | | - dispatch_semaphore_signal(sem); |
549 | | -#endif |
550 | | - } |
551 | | - |
552 | | - static void clean(hx::Object *inObj) { |
553 | | - hxSemaphore *l = dynamic_cast<hxSemaphore *>(inObj); |
554 | | - if (l) { |
555 | | - if(l->valid) { |
556 | | -#ifdef HX_WINDOWS |
557 | | - CloseHandle(l->sem); |
558 | | -#elif defined(POSIX_SEMAPHORE) |
559 | | - sem_destroy(&l->sem); |
560 | | -#endif |
561 | | - l->valid = false; |
562 | | - } |
563 | | - } |
564 | | - } |
565 | | -}; |
| 458 | +// --- Semaphore ------------------------------------------------------------ |
566 | 459 |
|
567 | 460 | Dynamic __hxcpp_semaphore_create(int value) { |
568 | | - return new hxSemaphore(value); |
| 461 | + return new hx::thread::CountingSemaphore_obj(value); |
569 | 462 | } |
570 | 463 | void __hxcpp_semaphore_acquire(Dynamic inSemaphore) { |
571 | | - hxSemaphore *semaphore = dynamic_cast<hxSemaphore *>(inSemaphore.mPtr); |
572 | | - if (!semaphore) |
573 | | - throw HX_INVALID_OBJECT; |
574 | | - semaphore->Acquire(); |
| 464 | + auto semaphore = inSemaphore.Cast<hx::thread::CountingSemaphore>(); |
| 465 | + |
| 466 | + semaphore->acquire(); |
575 | 467 | } |
576 | 468 | bool __hxcpp_semaphore_try_acquire(Dynamic inSemaphore, double timeout) { |
577 | | - hxSemaphore *semaphore = dynamic_cast<hxSemaphore *>(inSemaphore.mPtr); |
578 | | - if (!semaphore) |
579 | | - throw HX_INVALID_OBJECT; |
580 | | - return semaphore->TryAcquire(timeout); |
| 469 | + auto semaphore = inSemaphore.Cast<hx::thread::CountingSemaphore>(); |
| 470 | + |
| 471 | + return semaphore->tryAcquire(timeout); |
581 | 472 | } |
582 | 473 | void __hxcpp_semaphore_release(Dynamic inSemaphore) { |
583 | | - hxSemaphore *semaphore = dynamic_cast<hxSemaphore *>(inSemaphore.mPtr); |
584 | | - if (!semaphore) |
585 | | - throw HX_INVALID_OBJECT; |
586 | | - semaphore->Release(); |
| 474 | + auto semaphore = inSemaphore.Cast<hx::thread::CountingSemaphore>(); |
| 475 | + |
| 476 | + semaphore->release(); |
587 | 477 | } |
588 | 478 |
|
| 479 | +// --- Condition ------------------------------------------------------------ |
| 480 | + |
589 | 481 | Dynamic __hxcpp_condition_create(void) |
590 | 482 | { |
591 | 483 | return new hx::thread::ConditionVariable_obj(); |
|
0 commit comments