#endif
ks_pid_t;
+typedef enum {
+ KS_THREAD_INIT,
+ KS_THREAD_RUNNING,
+ KS_THREAD_FAIL,
+ KS_THREAD_SHUTDOWN,
+ KS_THREAD_STOPPED
+} ks_thread_state_t;
+
+#define KS_THREAD_IS_RUNNING(_thread) _thread->state == KS_THREAD_RUNNING
+
struct ks_thread {
ks_pool_t *pool;
#ifdef WIN32
ks_thread_function_t function;
size_t stack_size;
uint32_t flags;
- uint8_t running;
+ ks_thread_state_t state;
uint8_t priority;
void *return_data;
};
typedef enum {
KS_THREAD_FLAG_DEFAULT = 0,
- KS_THREAD_FLAG_DETATCHED = (1 << 0)
+ KS_THREAD_FLAG_DETACHED = (1 << 0)
} ks_thread_flags_t;
KS_DECLARE(int) ks_thread_set_priority(int nice_val);
switch(action) {
case KS_MPCL_ANNOUNCE:
- thread->running = 0;
+ if (thread->state == KS_THREAD_RUNNING) {
+ thread->state = KS_THREAD_SHUTDOWN;
+ }
break;
case KS_MPCL_TEARDOWN:
- if (!(thread->flags & KS_THREAD_FLAG_DETATCHED)) {
+ while(thread->state == KS_THREAD_SHUTDOWN) {
+ ks_sleep(10000);
+ }
+
+ if (!(thread->flags & KS_THREAD_FLAG_DETACHED)) {
ks_thread_join(thread);
}
break;
case KS_MPCL_DESTROY:
+
#ifdef WIN32
- //if (!(thread->flags & KS_THREAD_FLAG_DETATCHED)) {
- CloseHandle(thread->handle);
- //}
+ CloseHandle(thread->handle);
#endif
break;
}
pthread_setschedparam(tt, policy, ¶m);
}
#endif
-
+ thread->state = KS_THREAD_RUNNING;
thread->return_data = thread->function(thread, thread->private_data);
+ thread->state = KS_THREAD_STOPPED;
#ifndef WIN32
pthread_attr_destroy(&thread->attribute);
#endif
{
ks_thread_t *thread = NULL;
ks_status_t status = KS_STATUS_FAIL;
+ int sanity = 1000;
if (!rthread) goto done;
thread->private_data = data;
thread->function = func;
thread->stack_size = stack_size;
- thread->running = 1;
thread->flags = flags;
thread->priority = priority;
thread->pool = pool;
SetThreadPriority(thread->handle, THREAD_PRIORITY_LOWEST);
}
- if (flags & KS_THREAD_FLAG_DETATCHED) {
+ if (flags & KS_THREAD_FLAG_DETACHED) {
//CloseHandle(thread->handle);
}
if (pthread_attr_init(&thread->attribute) != 0)
goto fail;
- if ((flags & KS_THREAD_FLAG_DETATCHED) && pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0)
+ if ((flags & KS_THREAD_FLAG_DETACHED) && pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0)
goto failpthread;
if (thread->stack_size && pthread_attr_setstacksize(&thread->attribute, thread->stack_size) != 0)
goto done;
failpthread:
-
+ thread->state = KS_THREAD_FAIL;
pthread_attr_destroy(&thread->attribute);
#endif
fail:
if (thread) {
- thread->running = 0;
+ thread->state = KS_THREAD_FAIL;
if (pool) {
ks_pool_free(pool, &thread);
}
}
done:
if (status == KS_STATUS_SUCCESS) {
+ while(thread->state < KS_THREAD_RUNNING && --sanity > 0) {
+ ks_sleep(1000);
+ }
+
+ if (!sanity) {
+ status = KS_STATUS_FAIL;
+ goto fail;
+ }
+
*rthread = thread;
ks_pool_set_cleanup(pool, thread, NULL, 0, ks_thread_cleanup);
}
ks_mutex_unlock(tp->mutex);
while(need > 0) {
- if (ks_thread_create_ex(&thread, worker_thread, tp, KS_THREAD_FLAG_DETATCHED, tp->stack_size, tp->priority, tp->pool) != KS_STATUS_SUCCESS) {
+ if (ks_thread_create_ex(&thread, worker_thread, tp, KS_THREAD_FLAG_DETACHED, tp->stack_size, tp->priority, tp->pool) != KS_STATUS_SUCCESS) {
ks_mutex_lock(tp->mutex);
tp->thread_count--;
ks_mutex_unlock(tp->mutex);
ks_hash_iterator_t *itt;
ks_hash_t *hash = (ks_hash_t *) data;
- while(thread->running) {
+ while(KS_THREAD_IS_RUNNING(thread)) {
for (itt = ks_hash_first(hash, KS_READLOCKED); itt; itt = ks_hash_next(&itt)) {
const void *key;
void *val;
ks_hash_this(itt, &key, NULL, &val);
- printf("%d ITT %s=%s\n", (int)ks_thread_self_id(), (char *)key, (char *)val);
+ printf("%u ITT %s=%s\n", (int)ks_thread_self_id(), (char *)key, (char *)val);
}
ks_sleep(100000);
}
}
for (i = 0; i < ttl; i++) {
- threads[i]->running = 0;
+ threads[i]->state = KS_THREAD_SHUTDOWN;
ks_thread_join(threads[i]);
}
static void *thread_priority(ks_thread_t *thread, void *data)
{
- while (thread->running) {
- ks_sleep(1000000);
+ while (KS_THREAD_IS_RUNNING(thread)) {
+ ks_sleep(100000);
}
return NULL;
{
int d = (int)(intptr_t)data;
- while (thread->running) {
- ks_sleep(1000000);
+ while (KS_THREAD_IS_RUNNING(thread)) {
+ ks_sleep(100000);
}
if ( d == 1 ) {
int i;
for(i = 0; i < cpu_count; i++) {
- status = ks_thread_create_ex(&threads[i], thread_test_function_detatched, d, KS_THREAD_FLAG_DETATCHED, KS_THREAD_DEFAULT_STACK, KS_PRI_NORMAL, pool);
+ status = ks_thread_create_ex(&threads[i], thread_test_function_detatched, d, KS_THREAD_FLAG_DETACHED, KS_THREAD_DEFAULT_STACK, KS_PRI_NORMAL, pool);
ok( status == KS_STATUS_SUCCESS );
}
}
ks_status_t status;
void *d = (void *)(intptr_t)1;
- status = ks_thread_create_ex(&thread_p, thread_priority, d, KS_THREAD_FLAG_DETATCHED, KS_THREAD_DEFAULT_STACK, KS_PRI_IMPORTANT, pool);
+ status = ks_thread_create_ex(&thread_p, thread_priority, d, KS_THREAD_FLAG_DETACHED, KS_THREAD_DEFAULT_STACK, KS_PRI_IMPORTANT, pool);
ok( status == KS_STATUS_SUCCESS );
- ks_sleep(1000000);
+ ks_sleep(100000);
todo("Add check to see if has permission to set thread priority\n");
ok( ks_thread_priority(thread_p) == KS_PRI_IMPORTANT );
end_todo;