Skip to content

Commit

Permalink
Add thread-related NIF API
Browse files Browse the repository at this point in the history
  • Loading branch information
krestenkrab committed Sep 16, 2013
1 parent 7a1c5ef commit 0abda8b
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 1 deletion.
3 changes: 2 additions & 1 deletion jnif/Makefile
Expand Up @@ -24,7 +24,8 @@ OFILES= jnif.o \
jnif_errno.o \
jnif_dlopen.o \
jnif_sys.o \
jnif_process.o
jnif_process.o \
jnif_thread.o



Expand Down
137 changes: 137 additions & 0 deletions jnif/jnif_thread.cc
@@ -0,0 +1,137 @@

#include "jnif.h"

#include <pthread.h>

#ifdef __APPLE_CC__
struct init_arg {
const char *name;
void *arg;
void * (*fun)(void *);
};

//
// we use a separate start routine to be able to set the thread name on macosx
//
static void* jnif_macos_start_routine(void* a)
{
init_arg *init = (init_arg*)a;
if (init->name != NULL) {
pthread_setname_np(init->name);
}

void *arg = init->arg;
void * (*fun)(void *) = init->fun;

// free it, now we've taken the values
delete init;

// now go!
return (*fun)(arg);
}

#endif



int enif_thread_create(char *name,
ErlNifTid *tid,
void * (*start_routine)(void *),
void *args,
ErlNifThreadOpts *opts)
{
pthread_attr_t attr;

pthread_attr_init(&attr);

if (opts != NULL) {
pthread_attr_setstacksize(&attr, opts->suggested_stack_size);
}

#ifdef __APPLE_CC__
init_arg *thread_init = new init_arg();
thread_init->name = name;
thread_init->arg = args;
thread_init->fun = start_routine;
#endif

pthread_t thread;
int err = pthread_create(&thread,
&attr,
#ifdef __APPLE_CC__
&jnif_macos_start_routine,
thread_init
#else
start_routine,
args
#endif
);

if (err == 0 && tid != NULL) {
*tid = (ErlNifTid)thread;

#ifndef __APPLE_CC__

if (name != NULL) {
#ifdef __OpenBSD__
pthread_set_name_np(thread, name);
#endif
#ifdef LINUX
pthread_setname_np(thread, name);
#endif
}

#endif
}

pthread_attr_destroy(&attr);

return err;
}

void enif_thread_exit(void *resp)
{
pthread_exit(resp);
}

int enif_thread_join(ErlNifTid tid, void **respp)
{
return pthread_join((pthread_t)tid, respp);
}

ErlNifThreadOpts *enif_thread_opts_create(char *name)
{
return new ErlNifThreadOpts();
}

void enif_thread_opts_destroy(ErlNifThreadOpts *opts)
{
delete opts;
}

ErlNifTid enif_thread_self(void)
{
return (ErlNifTid) pthread_self();
}

int enif_tsd_key_create(char *name, ErlNifTSDKey *key)
{
int err = pthread_key_create((pthread_key_t*)key, NULL);
return err;
}

void enif_tsd_key_destroy(ErlNifTSDKey key)
{
pthread_key_delete((pthread_key_t) key);
}

void *enif_tsd_get(ErlNifTSDKey key)
{
return pthread_getspecific((pthread_key_t)key);
}

void enif_tsd_set(ErlNifTSDKey key, void *data)
{
pthread_setspecific((pthread_key_t)key, data);
}

0 comments on commit 0abda8b

Please sign in to comment.