Beispiel #1
0
static ErlDrvData start(ErlDrvPort port,
			char *command)
{
    Otp9302Data *data;
    ErlDrvSysInfo sys_info;

    data = driver_alloc(sizeof(Otp9302Data));
    if (!data)
	return ERL_DRV_ERROR_GENERAL;

    data->port = port;

    driver_system_info(&sys_info, sizeof(ErlDrvSysInfo));
    data->smp = sys_info.smp_support;

    if (!data->smp) {
	data->msgq.start = NULL;
	data->msgq.end = NULL;
	data->msgq.mtx = erl_drv_mutex_create("");
	if (!data->msgq.mtx) {
	    driver_free(data);
	    return ERL_DRV_ERROR_GENERAL;
	}
    }

    return (ErlDrvData) data;
}
Beispiel #2
0
static ErlDrvData
tcbdb_start    (ErlDrvPort     port,
                char*          buf)
{
  ErlDrvSysInfo info;
  TcDriverData* d = (TcDriverData*) driver_alloc (sizeof (TcDriverData));
  (void) buf;

  memset (d, 0, sizeof (TcDriverData));

  d->ref_count = 1;
  d->port = port;
  d->bdb = tcbdbnew ();
  driver_system_info (&info, sizeof (info));
  if (info.thread_support && info.async_threads > 0)
    {
      d->async_threads = 1;
    }
  d->cur = tcbdbcurnew (d->bdb);
  init_handlers (d->handlers);

  d->magic = ((intptr_t) d) >> 8;

  return (ErlDrvData) d;
}
Beispiel #3
0
static ErlDrvSSizeT control(ErlDrvData drv_data,
                            unsigned int command,
                            char *buf, ErlDrvSizeT len,
                            char **rbuf, ErlDrvSizeT rlen)
{
    char *res_str;
    PRINTF(("control(%p, %d, ...) called\r\n", drv_data, command));

    switch (command) {
    case ERTS_FP_THREAD_TEST: {
        ErlDrvTid tid;
        ErlDrvSysInfo info;
        driver_system_info(&info, sizeof(ErlDrvSysInfo));
        if (!info.thread_support)
            res_str = "skip: no thread support";
        else if (0 != erl_drv_thread_create("test", &tid, do_test, NULL, NULL))
            res_str = "failed to create thread";
        else if (0 != erl_drv_thread_join(tid, &res_str))
            res_str = "failed to join thread";
        break;
    }
    case ERTS_FP_CONTROL_TEST:
        res_str = do_test(NULL);
        break;
    default:
        res_str = "unknown command";
        break;
    }

done: {
        int res_len = strlen(res_str);
        if (res_len > rlen) {
            char *abuf = driver_alloc(sizeof(char)*res_len);
            if (!abuf)
                return 0;
            *rbuf = abuf;
        }

        memcpy((void *) *rbuf, (void *) res_str, res_len);

        return res_len;
    }
}
Beispiel #4
0
// Initialize thread structure
int dthread_init(dthread_t* thr, ErlDrvPort port)
{
    ErlDrvSysInfo sys_info;

    memset(thr, 0, sizeof(dthread_t));
    dthread_signal_init(thr);
    driver_system_info(&sys_info, sizeof(ErlDrvSysInfo));
    // smp_support is used for message passing from thread to
    // calling process. if SMP is supported the message will go
    // directly to sender, otherwise it must be sent to port 
    thr->smp_support = sys_info.smp_support;
    thr->port = port;
    thr->dport = driver_mk_port(port);
    thr->owner = driver_connected(port);

    if (!(thr->iq_mtx = erl_drv_mutex_create("iq_mtx")))
	return -1;
#ifdef __WIN32__
    // create a manual reset event
    if (!(thr->iq_signal[0] = (ErlDrvEvent)
	  CreateEvent(NULL, TRUE, FALSE, NULL))) {
	dthread_finish(thr);
	return -1;
    }
    DEBUGF("dthread_init: handle=%d", DTHREAD_EVENT(thr->iq_signal[0]));
#else
    {
	int pfd[2];
	if (pipe(pfd) < 0) {
	    dthread_finish(thr);
	    return -1;
	}
	DEBUGF("dthread_init: pipe[0]=%d,pidp[1]=%d", pfd[0], pfd[1]);
	thr->iq_signal[0] = (ErlDrvEvent) ((long)pfd[0]);
	thr->iq_signal[1] = (ErlDrvEvent) ((long)pfd[1]);
	INFOF("pipe: %d,%d", pfd[0], pfd[1]);
    }
#endif
    return 0;
}
Beispiel #5
0
// Called by the emulator when the driver is starting.
static ErlDrvData
start_driver(ErlDrvPort port, char *buff) {
    EdbcOciPortData *pd = zalloc(port, sizeof(EdbcOciPortData));
    if (pd == NULL) {
        // TODO: use ERL_DRV_ERROR_ERRNO and provide out-of-memory info
        return ERL_DRV_ERROR_GENERAL;
    }

    ErlDrvSysInfo sys_info;
    driver_system_info(&sys_info, sizeof(ErlDrvSysInfo));
    pd->send_term_requires_lock = (sys_info->smp_support == 0);
    pd->port = (void*)port;
    pd->owner = driver_connected(port);
    pd->mutex = erl_drv_mutex_create("edbc_oci_port_instance_mutex");

    // some fields can't be initialized until we've got our hands on 
    // the relevant configuration data at runtime...
    pd->worker_pool = NULL;
    pd->log = NULL;
    
    return (ErlDrvData)pd;
};
Beispiel #6
0
static int innostore_drv_init()
{
    char log_filename[_POSIX_PATH_MAX];
    size_t log_filename_size = sizeof(log_filename);
    ErlDrvSysInfo sys_info;

    G_ENGINE_STATE_LOCK = erl_drv_mutex_create("innostore_state_lock");
    G_LOGGER_LOCK = erl_drv_mutex_create("innostore_logger_lock");

    // Check if this is beam.smp - cannot run under beam 
    // due to restrictions with driver_send_term
    driver_system_info(&sys_info, sizeof(sys_info));
    if (sys_info.smp_support == 0)
    {
        log("Innostore only supports the SMP runtime, add -smp enable");
        return -1;
    }

    // Initialize Inno's memory subsystem
    if (ib_init() != DB_SUCCESS)
    {
        return -1;
    }

    // Set up the logger
    if (erl_drv_getenv("INNOSTORE_LOG", log_filename, &log_filename_size) == 0)
    {
        set_log_file(log_filename);
    }
    else
    {
        set_log_file(NULL);
    }

    return 0;
}
Beispiel #7
0
void enif_system_info(ErlNifSysInfo *sip, size_t si_size)
{
    driver_system_info(sip, si_size);
}
Beispiel #8
0
static int
control(ErlDrvData drv_data,
	unsigned int command,
	char *buf, int len,
	char **rbuf, int rlen)
{
    int res;
    char *str;
    size_t slen, slen2;
    ErlDrvPort port = (ErlDrvPort) drv_data;
    unsigned deadbeef[] = {0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef,
			   0xdeadbeef};
    ErlDrvSysInfo *sip = driver_alloc(ERL_DRV_SYS_INFO_SIZE + sizeof(deadbeef));
    char *beyond_end_format = "error: driver_system_info() wrote beyond end "
	"of the ErlDrvSysInfo struct";
    char *buf_overflow_format = "error: Internal buffer overflow";

    if (!sip) {
	driver_failure_atom(port, "enomem");
	return 0;
    }

    memset((char *) sip, 0xed, ERL_DRV_SYS_INFO_SIZE);
    memcpy(((char *) sip) + ERL_DRV_SYS_INFO_SIZE,
	   (char *) &deadbeef[0],
	   sizeof(deadbeef));

    driver_system_info(sip, ERL_DRV_SYS_INFO_SIZE);

    slen = sys_info_drv_max_res_len(sip);
    slen2 = strlen(beyond_end_format) + 1;
    if (slen2 > slen)
	slen = slen2;
    slen2 = strlen(buf_overflow_format) + 1;
    if (slen2 > slen)
	slen = slen2;
    str = driver_alloc(slen);
    if (!str) {
	driver_free(sip);
	driver_failure_atom(port, "enomem");
	return 0;
    }
    *rbuf = str;

    /* Check that the emulator didn't write beyond ERL_DRV_SYS_INFO_SIZE */
    if (memcmp(((char *) sip) + ERL_DRV_SYS_INFO_SIZE,
	       (char *) &deadbeef[0],
	       sizeof(deadbeef)) != 0) {
	res = sprintf(str, beyond_end_format);
    }
    else {
	res = sys_info_drv_sprintf_sys_info(sip, str);
	if (res > slen)
	    res = sprintf(str, buf_overflow_format);
    }
    driver_free(sip);
    return res;
}