Exemplo n.º 1
0
void
omni_thread::start(void)
{
    omni_mutex_lock l(mutex);

    if (_state != STATE_NEW)
	throw omni_thread_invalid();


    unsigned int t;
    handle = (HANDLE)_beginthreadex(
                        NULL,
			0,
			omni_thread_wrapper,
			(LPVOID)this,
			CREATE_SUSPENDED, 
			&t);
    nt_id = t;
    if (handle == NULL)
      throw omni_thread_fatal(GetLastError());

    if (!SetThreadPriority(handle, _priority))
      throw omni_thread_fatal(GetLastError());

    if (ResumeThread(handle) == 0xffffffff)
	throw omni_thread_fatal(GetLastError());

    _state = STATE_RUNNING;
}
Exemplo n.º 2
0
omni_thread::init_t::init_t(void)
{
    if (count++ != 0)   // only do it once however many objects get created.
        return;

    DB(cerr << "omni_thread::init: OS/2 implementation initialising\n");

    APIRET rc = DosAllocThreadLocalMemory( 1 , &self_tls_addr );
    if (rc != 0) throw omni_thread_fatal(rc);

    next_id_mutex = new omni_mutex;

    //
    // Create object for this (i.e. initial) thread.
    //

    omni_thread* t = new omni_thread;

    t->_state = STATE_RUNNING;
    t->handle = *_threadid;

    DB(cerr << "initial thread " << t->id() << " OS/2 thread id " << t->handle << endl);

    *self_tls_addr = (ULONG)t;

    rc = DosSetPriority( PRTYS_THREAD , os2_priority(PRIORITY_NORMAL) , 0 , t->handle );
    if ( rc != 0 )
        throw omni_thread_fatal(rc);
}
Exemplo n.º 3
0
omni_thread::~omni_thread(void)
{
    DB(cerr << "destructor called for thread " << id() << endl);
    if (handle && !CloseHandle(handle))
    throw omni_thread_fatal(GetLastError());
    if (cond_semaphore && !CloseHandle(cond_semaphore))
    throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 4
0
omni_thread::~omni_thread(void)
{
    DB(cerr << "destructor called for thread " << id() << endl);
// sf@ - _endthread() that is used for BCC already does a CloseHandle (that's not the case for _endthreadEx())
// #ifndef __BCPLUSPLUS__
    if (handle && !CloseHandle(handle))
	throw omni_thread_fatal(GetLastError());
// #endif
    if (cond_semaphore && !CloseHandle(cond_semaphore))
	throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 5
0
  inline omni_thread_dummy() : omni_thread()
  {
    _dummy = 1;
    _state = STATE_RUNNING;

    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
			 GetCurrentProcess(), &handle,
			 0, FALSE, DUPLICATE_SAME_ACCESS))
      throw omni_thread_fatal(GetLastError());

    nt_id = GetCurrentThreadId();

    if (!TlsSetValue(self_tls_index, (LPVOID)this))
      throw omni_thread_fatal(GetLastError());
  }
Exemplo n.º 6
0
void
omni_condition::wait(void)
{
    _internal_omni_thread_helper me;

    EnterCriticalSection(&crit);

    me->cond_next = NULL;
    me->cond_prev = waiting_tail;
    if (waiting_head == NULL)
    waiting_head = me;
    else
    waiting_tail->cond_next = me;
    waiting_tail = me;
    me->cond_waiting = TRUE;

    LeaveCriticalSection(&crit);

    mutex->unlock();

    DWORD result = WaitForSingleObject(me->cond_semaphore, INFINITE);

    mutex->lock();

    if (result != WAIT_OBJECT_0)
    throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 7
0
void omni_thread::join(void** status)
{
    mutex.lock();

    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
        mutex.unlock();
        throw omni_thread_invalid();
    }

    mutex.unlock();

    if (this == self())
        throw omni_thread_invalid();

    if (detached)
        throw omni_thread_invalid();

    DB(cerr << "omni_thread::join: doing DosWaitThread\n");

    APIRET rc = DosWaitThread( &handle , DCWW_WAIT );
    if ( rc != 0 )
        throw omni_thread_fatal(rc);

    DB(cerr << "omni_thread::join: DosWaitThread succeeded\n");

    if (status)
      *status = return_val;

    delete this;
}
Exemplo n.º 8
0
void omni_condition::wait(void)
{
    _internal_omni_thread_helper me;

    DosRequestMutexSem( crit , SEM_INDEFINITE_WAIT );

    me->cond_next = NULL;
    me->cond_prev = waiting_tail;
    if (waiting_head == NULL)
    waiting_head = me;
    else
    waiting_tail->cond_next = me;
    waiting_tail = me;
    me->cond_waiting = TRUE;

    DosReleaseMutexSem( crit );

    mutex->unlock();

    APIRET result =  DosWaitEventSem(me->cond_semaphore, SEM_INDEFINITE_WAIT);
    ULONG c;
    DosResetEventSem(me->cond_semaphore,&c);

    mutex->lock();

    if (result != 0) throw omni_thread_fatal(result);
}
Exemplo n.º 9
0
void
omni_thread::common_constructor(void* arg, priority_t pri, int det)
{
    _state = STATE_NEW;
    _priority = pri;

    next_id_mutex->lock();
    _id = next_id++;
    next_id_mutex->unlock();

    thread_arg = arg;
    detached = det;	// may be altered in start_undetached()

    cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL);

    if (cond_semaphore == NULL)
	throw omni_thread_fatal(GetLastError());

    cond_next = cond_prev = NULL;
    cond_waiting = FALSE;

    handle = NULL;

    _dummy       = 0;
    _values      = 0;
    _value_alloc = 0;
}
Exemplo n.º 10
0
void
omni_thread::join(void** status)
{
    mutex.lock();

    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
    mutex.unlock();
    throw omni_thread_invalid();
    }

    mutex.unlock();

    if (this == self())
    throw omni_thread_invalid();

    if (detached)
    throw omni_thread_invalid();

    DB(cerr << "omni_thread::join: doing WaitForSingleObject\n");

    if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0)
    throw omni_thread_fatal(GetLastError());

    DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n");

    if (status)
      *status = return_val;

    delete this;
}
Exemplo n.º 11
0
omni_semaphore::~omni_semaphore(void)
{
  if (!CloseHandle(nt_sem)) {
    DB( cerr << "omni_semaphore::~omni_semaphore: CloseHandle error "
         << GetLastError() << endl );
    throw omni_thread_fatal(GetLastError());
  }
}
Exemplo n.º 12
0
void omni_semaphore::wait(void)
{
    ULONG cnt;
    APIRET rc = DosWaitEventSem(nt_sem, SEM_INDEFINITE_WAIT);
    if (rc != 0)
    throw omni_thread_fatal(rc);
    DosResetEventSem(nt_sem,&cnt);
}
Exemplo n.º 13
0
void omni_thread::start(void)
{
    omni_mutex_lock l(mutex);

    if (_state != STATE_NEW)
        throw omni_thread_invalid();

    handle = _beginthread(omni_thread_wrapper,NULL,stack_size,(void*)this);

    if ( handle == -1 )
        throw omni_thread_fatal(errno);

    APIRET rc = DosSetPriority( PRTYS_THREAD , os2_priority(_priority) , 0 , handle );
    if ( rc != 0 )
        throw omni_thread_fatal(rc);

    _state = STATE_RUNNING;
}
Exemplo n.º 14
0
omni_semaphore::~omni_semaphore(void)
{
   APIRET rc = DosCloseEventSem( nt_sem );
  if (rc!=0) {
    DB( cerr << "omni_semaphore::~omni_semaphore: DosCloseEventSem error "
         << rc << endl );
    throw omni_thread_fatal(rc);
  }
}
Exemplo n.º 15
0
omni_thread::~omni_thread(void)
{
    DB(cerr << "destructor called for thread " << id() << endl);
    if (_values) {
        for (key_t i=0; i < _value_alloc; i++) {
	    if (_values[i]) {
	        delete _values[i];
	    }
        }
	delete [] _values;
    }
// sf@ - _endthread() that is used for BCC already does a CloseHandle (that's not the case for _endthreadEx())
// #ifndef __BCPLUSPLUS__
    if (handle && !CloseHandle(handle))
	throw omni_thread_fatal(GetLastError());
// #endif
    if (cond_semaphore && !CloseHandle(cond_semaphore))
	throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 16
0
omni_semaphore::omni_semaphore(unsigned int initial)
{
    APIRET rc = DosCreateEventSem( NULL , &nt_sem , 0 , FALSE );

    if (rc != 0 ) {
      DB( cerr << "omni_semaphore::omni_semaphore: DosCreateEventSem error "
         << rc << endl );
      throw omni_thread_fatal(rc);
    }
}
Exemplo n.º 17
0
omni_semaphore::omni_semaphore(unsigned int initial)
{
    nt_sem = CreateSemaphore(NULL, initial, SEMAPHORE_MAX, NULL);

    if (nt_sem == NULL) {
      DB( cerr << "omni_semaphore::omni_semaphore: CreateSemaphore error "
         << GetLastError() << endl );
      throw omni_thread_fatal(GetLastError());
    }
}
Exemplo n.º 18
0
void
omni_thread::start(void)
{
    omni_mutex_lock l(mutex);

    if (_state != STATE_NEW)
    throw omni_thread_invalid();

#ifndef __BCPLUSPLUS__
    // MSVC++ or compatiable
    unsigned int t;
    handle = (HANDLE)_beginthreadex(
                        NULL,
            0,
            omni_thread_wrapper,
            (LPVOID)this,
            CREATE_SUSPENDED, 
            &t);
    nt_id = t;
    if (handle == NULL)
      throw omni_thread_fatal(GetLastError());
#else
    // Borland C++
    handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,
                    0,
                    (void*)this,
                    NULL,
                    CREATE_SUSPENDED,
                    &nt_id);
    if (handle == INVALID_HANDLE_VALUE)
      throw omni_thread_fatal(errno);
#endif

    if (!SetThreadPriority(handle, nt_priority(_priority)))
      throw omni_thread_fatal(GetLastError());

    if (ResumeThread(handle) == 0xffffffff)
    throw omni_thread_fatal(GetLastError());

    _state = STATE_RUNNING;
}
Exemplo n.º 19
0
void omni_thread::set_priority(priority_t pri)
{
    omni_mutex_lock l(mutex);

    if (_state != STATE_RUNNING)
        throw omni_thread_invalid();

    _priority = pri;

    APIRET rc = DosSetPriority( PRTYS_THREAD , os2_priority(pri) , 0 , handle );
    if ( rc != 0 )
        throw omni_thread_fatal(rc);
}
Exemplo n.º 20
0
void
omni_thread::set_priority(priority_t pri)
{
    omni_mutex_lock l(mutex);

    if (_state != STATE_RUNNING)
    throw omni_thread_invalid();

    _priority = pri;

    if (!SetThreadPriority(handle, nt_priority(pri)))
    throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 21
0
omni_thread::init_t::init_t(void)
{
    if (count++ != 0)   // only do it once however many objects get created.
    return;

    DB(cerr << "omni_thread::init: NT implementation initialising\n");

    self_tls_index = TlsAlloc();

    if (self_tls_index == 0xffffffff)
    throw omni_thread_fatal(GetLastError());

    next_id_mutex = new omni_mutex;

    //
    // Create object for this (i.e. initial) thread.
    //

    omni_thread* t = new omni_thread;

    t->_state = STATE_RUNNING;

    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
             GetCurrentProcess(), &t->handle,
             0, FALSE, DUPLICATE_SAME_ACCESS))
    throw omni_thread_fatal(GetLastError());

    t->nt_id = GetCurrentThreadId();

    DB(cerr << "initial thread " << t->id() << " NT thread id " << t->nt_id
       << endl);

    if (!TlsSetValue(self_tls_index, (LPVOID)t))
    throw omni_thread_fatal(GetLastError());

    if (!SetThreadPriority(t->handle, nt_priority(PRIORITY_NORMAL)))
    throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 22
0
int
omni_semaphore::trywait(void)
{
    switch (WaitForSingleObject(nt_sem, 0)) {

    case WAIT_OBJECT_0:
    return 1;
    case WAIT_TIMEOUT:
    return 0;
    }

    throw omni_thread_fatal(GetLastError());
    return 0; /* keep msvc++ happy */
}
Exemplo n.º 23
0
int
omni_semaphore::trywait(void)
{
    APIRET rc = DosWaitEventSem(nt_sem, SEM_IMMEDIATE_RETURN );
    switch ( rc )
    {

        case 0:
            return 1;
        case ERROR_TIMEOUT:
            return 0;
    }

    throw omni_thread_fatal(rc);
    return 0; /* keep msvc++ happy */
}
Exemplo n.º 24
0
unsigned __stdcall
#else
void _USERENTRY
#endif
omni_thread_wrapper(void* ptr)
{
    omni_thread* me = (omni_thread*)ptr;

    DB(cerr << "omni_thread_wrapper: thread " << me->id()
       << " started\n");

    if (!TlsSetValue(self_tls_index, (LPVOID)me))
    throw omni_thread_fatal(GetLastError());

    //
    // Now invoke the thread function with the given argument.
    //

    if (me->fn_void != NULL) {
    (*me->fn_void)(me->thread_arg);
    omni_thread::exit();
    }

    if (me->fn_ret != NULL) {
    void* return_value = (*me->fn_ret)(me->thread_arg);
    omni_thread::exit(return_value);
    }

    if (me->detached) {
    me->run(me->thread_arg);
    omni_thread::exit();
    } else {
    void* return_value = me->run_undetached(me->thread_arg);
    omni_thread::exit(return_value);
    }

    // should never get here.
#ifndef __BCPLUSPLUS__
    return 0;
#endif
}
Exemplo n.º 25
0
void omni_thread::common_constructor(void* arg, priority_t pri, int det)
{
    _state = STATE_NEW;
    _priority = pri;

    next_id_mutex->lock();
    _id = next_id++;
    next_id_mutex->unlock();

    thread_arg = arg;
    detached = det; // may be altered in start_undetached()

    APIRET rc = DosCreateEventSem( NULL , &cond_semaphore , 0 , FALSE );

    if (rc != 0)
        throw omni_thread_fatal(rc);

    cond_next = cond_prev = NULL;
    cond_waiting = FALSE;

    handle = NULL;
}
Exemplo n.º 26
0
void omni_condition::broadcast(void)
{
    DosRequestMutexSem( crit , SEM_INDEFINITE_WAIT );

    while (waiting_head != NULL) {
    omni_thread* t = waiting_head;
    waiting_head = t->cond_next;
    if (waiting_head == NULL)
        waiting_tail = NULL;
    else
        waiting_head->cond_prev = NULL;
    t->cond_waiting = FALSE;

    APIRET rc;
    if ((rc=DosPostEventSem(t->cond_semaphore))!=0 ) {
        DosReleaseMutexSem( crit );
        throw omni_thread_fatal(rc);
    }
    }

    DosReleaseMutexSem( crit );
}
Exemplo n.º 27
0
void
omni_condition::broadcast(void)
{
    EnterCriticalSection(&crit);

    while (waiting_head != NULL) {
    omni_thread* t = waiting_head;
    waiting_head = t->cond_next;
    if (waiting_head == NULL)
        waiting_tail = NULL;
    else
        waiting_head->cond_prev = NULL;
    t->cond_waiting = FALSE;

    if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
        int rc = GetLastError();
        LeaveCriticalSection(&crit);
        throw omni_thread_fatal(rc);
    }
    }

    LeaveCriticalSection(&crit);
}
Exemplo n.º 28
0
int
omni_condition::timedwait(unsigned long abs_sec, unsigned long abs_nsec)
{
    _internal_omni_thread_helper me;

    EnterCriticalSection(&crit);

    me->cond_next = NULL;
    me->cond_prev = waiting_tail;
    if (waiting_head == NULL)
    waiting_head = me;
    else
    waiting_tail->cond_next = me;
    waiting_tail = me;
    me->cond_waiting = TRUE;

    LeaveCriticalSection(&crit);

    mutex->unlock();

    unsigned long now_sec, now_nsec;

    get_time_now(&now_sec, &now_nsec);

    DWORD timeout;
    if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec)))
      timeout = 0;
    else {
      timeout = (abs_sec-now_sec) * 1000;

      if( abs_nsec < now_nsec )  timeout -= (now_nsec-abs_nsec) / 1000000;
      else                       timeout += (abs_nsec-now_nsec) / 1000000;
    }

    DWORD result = WaitForSingleObject(me->cond_semaphore, timeout);

    if (result == WAIT_TIMEOUT) {
    EnterCriticalSection(&crit);

    if (me->cond_waiting) {
        if (me->cond_prev != NULL)
        me->cond_prev->cond_next = me->cond_next;
        else
        waiting_head = me->cond_next;
        if (me->cond_next != NULL)
        me->cond_next->cond_prev = me->cond_prev;
        else
        waiting_tail = me->cond_prev;
        me->cond_waiting = FALSE;

        LeaveCriticalSection(&crit);

        mutex->lock();
        return 0;
    }

    //
    // We timed out but another thread still signalled us.  Wait for
    // the semaphore (it _must_ have been signalled) to decrement it
    // again.  Return that we were signalled, not that we timed out.
    //

    LeaveCriticalSection(&crit);

    result = WaitForSingleObject(me->cond_semaphore, INFINITE);
    }

    if (result != WAIT_OBJECT_0)
    throw omni_thread_fatal(GetLastError());

    mutex->lock();
    return 1;
}
Exemplo n.º 29
0
void
omni_semaphore::post(void)
{
    if (!ReleaseSemaphore(nt_sem, 1, NULL))
    throw omni_thread_fatal(GetLastError());
}
Exemplo n.º 30
0
void
omni_semaphore::wait(void)
{
    if (WaitForSingleObject(nt_sem, INFINITE) != WAIT_OBJECT_0)
    throw omni_thread_fatal(GetLastError());
}