ChimpLWHash * chimp_lwhash_new (void) { ChimpLWHash *self = CHIMP_MALLOC(ChimpLWHash, sizeof(*self)); if (self == NULL) { return NULL; } self->items = NULL; self->size = 0; return self; }
ChimpTaskInternal * chimp_task_new_main (void *stack_start) { sigset_t set; ChimpTaskInternal *task; sigemptyset (&set); sigaddset (&set, SIGPIPE); if (pthread_sigmask (SIG_BLOCK, &set, NULL) != 0) { CHIMP_BUG ("could not set signal mask on task thread"); return NULL; } signal (SIGPIPE, SIG_IGN); task = CHIMP_MALLOC(ChimpTaskInternal, sizeof(*task)); if (task == NULL) { return NULL; } main_task = task; memset (task, 0, sizeof (*task)); task->flags = CHIMP_TASK_FLAG_MAIN; task->gc = chimp_gc_new (stack_start); if (task->gc == NULL) { CHIMP_FREE (task); return NULL; } chimp_task_init_per_thread_key_once (task); if (pthread_mutex_init (&task->lock, NULL) != 0) { chimp_gc_delete (task->gc); chimp_vm_delete (task->vm); CHIMP_FREE (task); return NULL; } if (pthread_cond_init (&task->flags_cond, NULL) != 0) { pthread_mutex_destroy (&task->lock); chimp_gc_delete (task->gc); chimp_vm_delete (task->vm); CHIMP_FREE (task); return NULL; } CHIMP_TASK_LOCK(task); return task; }
ChimpRef * chimp_task_new (ChimpRef *callable) { ChimpRef *taskobj; pthread_attr_t attrs; ChimpTaskInternal *task = CHIMP_MALLOC(ChimpTaskInternal, sizeof(*task)); if (task == NULL) { return NULL; } memset (task, 0, sizeof (*task)); /* XXX can we guarantee callable won't be collected? think so ... */ task->method = callable; task->flags = 0; /* !!! important to incref *BEFORE* we start the task thread !!! */ /* (otherwise, short-lived tasks can prematurely kill the TaskInternal) */ task->refs++; if (pthread_mutex_init (&task->lock, NULL) != 0) { CHIMP_FREE (task); return NULL; } if (pthread_cond_init (&task->flags_cond, NULL) != 0) { pthread_mutex_destroy (&task->lock); CHIMP_FREE (task); return NULL; } if (pthread_attr_init (&attrs) != 0) { pthread_cond_destroy (&task->flags_cond); pthread_mutex_destroy (&task->lock); return NULL; } if (pthread_attr_setdetachstate (&attrs, PTHREAD_CREATE_DETACHED) != 0) { pthread_attr_destroy (&attrs); pthread_cond_destroy (&task->flags_cond); pthread_mutex_destroy (&task->lock); return NULL; } CHIMP_TASK_LOCK(task); if (pthread_create (&task->thread, &attrs, chimp_task_thread_func, task) != 0) { pthread_attr_destroy (&attrs); pthread_cond_destroy (&task->flags_cond); pthread_mutex_destroy (&task->lock); CHIMP_FREE (task); return NULL; } pthread_attr_destroy (&attrs); /* XXX error handling code is probably all kinds of wrong/unsafe from * this point, but meh. */ while (!CHIMP_TASK_IS_READY(task)) { if (pthread_cond_wait (&task->flags_cond, &task->lock) != 0) { CHIMP_TASK_UNLOCK(task); pthread_cond_destroy (&task->flags_cond); pthread_mutex_destroy (&task->lock); CHIMP_FREE (task); return NULL; } } /* create a heap-local handle for this task */ taskobj = chimp_class_new_instance (chimp_task_class, NULL); if (taskobj == NULL) { CHIMP_TASK_UNLOCK (task); pthread_cond_destroy (&task->flags_cond); pthread_mutex_destroy (&task->lock); CHIMP_FREE (task); return NULL; } CHIMP_TASK(taskobj)->priv = task; CHIMP_TASK(taskobj)->local = CHIMP_FALSE; CHIMP_TASK_UNLOCK(task); return taskobj; }