コード例 #1
0
ファイル: otp_9302_drv.c プロジェクト: caox/otp
static void output(ErlDrvData drv_data,
		   char *buf, ErlDrvSizeT len)
{
    Otp9302Data *data = (Otp9302Data *) drv_data;
    ErlDrvTermData td_port = driver_mk_port(data->port);
    ErlDrvTermData td_receiver = driver_caller(data->port);
    ErlDrvTermData td_job = driver_mk_atom("job");
    unsigned int key = (unsigned int) (ErlDrvSInt) data->port;
    long id[5];
    Otp9302AsyncData *ad[5];
    int i;

    for (i = 0; i < sizeof(ad)/sizeof(ad[0]); i++) {
	ad[i] = driver_alloc(sizeof(Otp9302AsyncData));
	if (!ad[i])
	    abort();

	ad[i]->smp = data->smp;
	ad[i]->port = data->port;
	ad[i]->block = 0;
	ad[i]->refc = 1;
	ad[i]->term_data.port = td_port;
	ad[i]->term_data.receiver = td_receiver;
	ad[i]->term_data.msg = td_job;
	ad[i]->msgq = &data->msgq;
    }
    ad[0]->block = 1;
    ad[0]->term_data.msg = driver_mk_atom("block");
    ad[2]->term_data.msg = driver_mk_atom("cancel");
    ad[4]->term_data.msg = driver_mk_atom("end_of_jobs");
    for (i = 0; i < sizeof(id)/sizeof(id[0]); i++)
	id[i] = driver_async(data->port, &key, async_invoke, ad[i], driver_free);
    if (id[2] > 0)
	driver_async_cancel(id[2]);
}
コード例 #2
0
ファイル: spidermonkey_drv.c プロジェクト: jonte/erlang_js
static void process(ErlDrvData handle, ErlIOVec *ev) {
  spidermonkey_drv_t *dd = (spidermonkey_drv_t *) handle;
  char *data = ev->binv[1]->orig_bytes;
  char *command = read_command(&data);
  if (strncmp(command, "ij", 2) == 0) {
    char *call_id = read_string(&data);
    int thread_stack = read_int32(&data);
    if (thread_stack < 8) {
      thread_stack = 8;
    }
    thread_stack = thread_stack * (1024 * 1024);
    int heap_size = read_int32(&data) * (1024 * 1024);
    dd->vm = sm_initialize(thread_stack, heap_size);
    send_ok_response(dd, call_id);
    driver_free(call_id);
  }
  else {
    js_call *call_data = (js_call *) driver_alloc(sizeof(js_call));
    call_data->driver_data = dd;
    call_data->args = ev->binv[1];
    driver_binary_inc_refc(call_data->args);
    ErlDrvPort port = dd->port;
    unsigned long thread_key = (unsigned long) port;
    driver_async(dd->port, (unsigned int *) &thread_key, (asyncfun) run_js, (void *) call_data, NULL);
  }
  driver_free(command);
}
コード例 #3
0
ファイル: tcbdberl.c プロジェクト: andrew-d/tcerl
static void
tcbdb_output           (ErlDrvData     handle,
                        char*          buf,
                        int            buflen)
{
  TcDriverData* d = (TcDriverData*) handle;
  FromEmulator from = decode_from (d, buf, buflen);

  switch (from.type)
    {
      case EMULATOR_REQUEST_INVALID:
        reply_string (d->port, driver_caller (d->port), "invalid request");

        break;

      default:
        driver_async (d->port,
                      &d->magic,
                      async_invoke,
                      from_emulator_dup (&from),
                      async_free);

        break;
    }
}
コード例 #4
0
ファイル: exp1_drv.c プロジェクト: e42s/jungerl
PRIVATESTUFF int
exp1_read(descriptor *d, char *buf, int buflen)
{
    char		cmd;
    struct t_data	*td = sys_alloc(sizeof(struct t_data));

    assert(td != NULL);
    assert(buflen >= 4);
    cmd = *buf++;
    td->cmd = cmd;
    td->id = get_int32(buf);
    buf += 4;
    td->name = NULL;

    fprintf(DEBUGIO, "exp1_read: cmd = %d, id = %ld\r\n", cmd, td->id);
    switch (cmd) {
    case EXP1_REQ_GETHOSTBYNAME:
        /* buf = null-terminated hostname */
        /* XXX use something other than strdup()? */
        td->name = strdup(buf);
        driver_async(d->port, KEY, invoke_gethostbyname, (void *) td,
                     free_t_data);
        break;
    }
    /*
    ** XXX I guess we'll ignore everything else, let the caller hang.
    */
    fprintf(DEBUGIO, "exp1_read: done\r\n");
    return 0;
}
コード例 #5
0
ファイル: gen_q_drv.c プロジェクト: csurface/gen_q
static void gen_q_drv_output(ErlDrvData handle, char *buff,
        ErlDrvSizeT bufflen) {
    GenQData *d = (GenQData*)handle;

    QWork* work = genq_alloc_work(buff, bufflen);
    if(work->op == FUNC_OPTS) {
        LOG("received opts %ld\n", work->op);
        copy_qopts((QOpts*)work->data, &d->opts);
        genq_free_work(work);

        LOG("responding %s\n", "ok");
        ei_x_buff ok;
        ei_x_new(&ok);
        ei_x_encode_ok(&ok);
        driver_output(d->port, ok.buff, ok.index);
        ei_x_free(&ok);
        return;
    } else if(work->data == NULL) {
        genq_free_work(work);
        ei_x_buff error;
        ei_x_new(&error);
        ei_x_encode_error_tuple_atom(&error, "badarg");
        driver_output(d->port, error.buff, error.index);
        ei_x_free(&error);
        return;
    }
    work->opts = &d->opts;

    driver_async(d->port, work->dispatch_key,
            genq_work,
            work,
            genq_free_work);
}
コード例 #6
0
ファイル: av_decoder.c プロジェクト: alepharchives/avcodec
static void av_decoder_schedule_decode(ErlDrvData drv_data, ErlIOVec *ev)
{
  H264Decoder* d = (H264Decoder*)drv_data;
  //  av_log(d->dec,AV_LOG_WARNING,"\nVSIZE:: %i\n");
  ErlDrvBinary *h264 = NULL;
  int i;
  for(i = 0; i < ev->vsize; i++) {
    if(h264 && ev->binv[i]) {
      driver_failure_atom(d->port, "invalid_output_vector");
      return;
    }
    if(ev->binv[i]) h264 = ev->binv[i];
  }
  if(!h264) {
    driver_failure_atom(d->port, "invalid_output_vector");
    return;
  }
  H264Frame *frame = driver_alloc(sizeof(H264Frame));
  bzero(frame, sizeof(H264Frame));
  frame->h264 = h264;
  // av_log(NULL,AV_LOG_INFO,"Size:: %i ",h264->orig_size);
  frame->decoder = d;
  driver_binary_inc_refc(h264);
  // I must change driver_free for other, more clever clearer, because yuv field must be also freed.
  driver_async(d->port, &d->key, av_async_decode, frame, driver_free);
}
コード例 #7
0
ファイル: gd_drv.c プロジェクト: alepharchives/ef_gd
static void output(ErlDrvData handle, char *buff, int len) {
  Gd *gd = (Gd*)handle;
  char cmd = buff[0];
  char *data = &buff[1];
  int size = len-1;
  asyncFun function;
  
  Cmd *command = driver_alloc(sizeof(Cmd) + size);
  command->gd = gd;
  command->size = size;
  memcpy(command->data, data, size);
  
  switch(cmd) {
  case SIZE:
    function = get_size;
    break;
  case READ:
    function = read_image;
    break;
  case RESIZE:
    function = resize;
    break;
  case BLOB:
    function = get_blob;
    break;
  case CROP:
    function = crop;
    break;
  }
  //function(command);
  //driver_free(command);
  driver_async(gd->port, NULL, function, command, driver_free);
}
コード例 #8
0
int main() {
    int i;
    init_async();
    for (i = 0; i < 30; i++) {
        AsyncData* d = (AsyncData*) malloc(sizeof (AsyncData));
        d->key = i;
        d->value = i;
        int c = i;
        driver_async((unsigned int*) & c, io_test, d, NULL);
    }
    printf("the result\n");
    pthread_t main_thread = pthread_self();
    pthread_exit(&main_thread);
    return 0;
}
コード例 #9
0
ファイル: async_blast_drv.c プロジェクト: 0x00evil/otp
static void output(ErlDrvData drv_data,
		   char *buf, ErlDrvSizeT len)
{
    async_blast_data_t *abd = (async_blast_data_t *) drv_data;
    if (abd->counter == 0) {
	int i;
	abd->caller = driver_caller(abd->port);
	abd->counter = NO_ASYNC_JOBS;
	for (i = 0; i < NO_ASYNC_JOBS; i++) {
	    if (0 > driver_async(abd->port, NULL, async_invoke, NULL, NULL)) {
		driver_failure_atom(abd->port, "driver_async_failed");
		break;
	    }
	}
    }
}
コード例 #10
0
ファイル: test_driver.c プロジェクト: erszcz/tracerl
static void test_drv_output(ErlDrvData handle, char *buff,
                            ErlDrvSizeT bufflen) {
  test_data* d = (test_data*)handle;
  test_async_data* ad = (test_async_data*)driver_alloc(sizeof(test_async_data));
  char method = buff[0], fn = buff[1], arg = buff[2], res;
  switch (method) {
  case 1:
    res = (char) do_f(fn, arg);
    driver_output(d->port, &res, 1);
    break;
  case 2:
    ad->fn = fn;
    ad->arg = arg;
    driver_async(d->port, NULL, do_async, (void *) ad, NULL);
  }
}
コード例 #11
0
ファイル: sqlite3_drv.c プロジェクト: mwpark/sqlite-erlang
static int sql_exec_script(sqlite3_drv_t *drv, char *command, int command_size) {
  async_sqlite3_command *async_command = make_async_command_script(drv, command, command_size);

#ifdef DEBUG
  fprintf(drv->log, "Driver async: %d %p\n", SQLITE_VERSION_NUMBER, async_command->statement);
  fflush(drv->log);
#endif

  if (sqlite3_threadsafe()) {
    drv->async_handle = driver_async(drv->port, &drv->key, sql_exec_async,
                                     async_command, sql_free_async);
  } else {
    sql_exec_async(async_command);
    ready_async((ErlDrvData) drv, (ErlDrvThreadData) async_command);
  }
  return 0;
}
コード例 #12
0
ファイル: test_driver.c プロジェクト: erszcz/tracerl
static void test_drv_outputv(ErlDrvData handle, ErlIOVec *ev) {
  test_data* d = (test_data*)handle;
  test_async_data* ad = (test_async_data*)driver_alloc(sizeof(test_async_data));
  size_t p, q;
  char method, fn, arg, res;
  p = 0; q = 1;
  EV_GET_CHAR(ev, &method, &p, &q);
  EV_GET_CHAR(ev, &fn, &p, &q);
  EV_GET_CHAR(ev, &arg, &p, &q);
  switch (method) {
  case 1:
    res = (char) do_f(fn, arg);
    driver_output(d->port, &res, 1);
    break;
  case 2:
    ad->fn = fn;
    ad->arg = arg;
    driver_async(d->port, NULL, do_async, (void *) ad, NULL);
  }
}
コード例 #13
0
ファイル: tcbdberl.c プロジェクト: andrew-d/tcerl
static void
tcbdb_stop      (ErlDrvData      handle)
{
  TcDriverData* d = (TcDriverData*) handle;

  if (d->open)
    {
      FromEmulator from;

      from.type = EMULATOR_REQUEST_BDB_CLOSE_ASYNC;
      from.d = d;

      /* is this allowed here (?) */

      driver_async (d->port,
                    &d->magic,
                    async_invoke,
                    from_emulator_dup (&from),
                    async_free);
    }

  data_unref (d);
}
コード例 #14
0
ファイル: sqlite3_drv.c プロジェクト: mwpark/sqlite-erlang
static int prepared_step(sqlite3_drv_t *drv, char *buffer, int buffer_size) {
  unsigned int prepared_index;
  long long_prepared_index;
  int index = 0;
  sqlite3_stmt *statement;
  async_sqlite3_command *async_command;

  ei_decode_version(buffer, &index, NULL);
  ei_decode_long(buffer, &index, &long_prepared_index);
  prepared_index = (unsigned int) long_prepared_index;

  if (prepared_index >= drv->prepared_count) {
#ifdef DEBUG
    fprintf(drv->log, "Tried to make a step in prepared statement #%d, but maximum possible is #%d\n", prepared_index, drv->prepared_count - 1);
    fflush(drv->log);
#endif      
    return output_error(drv, SQLITE_MISUSE,
                        "Trying to evaluate non-existent prepared statement");
  }

#ifdef DEBUG
  fprintf(drv->log, "Making a step in prepared statement #%d\n", prepared_index);
  fflush(drv->log);
#endif

  statement = drv->prepared_stmts[prepared_index];
  async_command = make_async_command_statement(drv, statement);

  if (sqlite3_threadsafe()) {
    drv->async_handle = driver_async(drv->port, &drv->key, sql_step_async,
                                     async_command, sql_free_async);
  } else {
    sql_step_async(async_command);
    ready_async((ErlDrvData) drv, (ErlDrvThreadData) async_command);
  }
  return 0;
}
コード例 #15
0
ファイル: erlxsl.c プロジェクト: chinnurtb/erlxsl
/*
This function is called whenever the port is written to. The port should be in binary mode, see open_port/2.
The ErlIOVec contains both a SysIOVec, suitable for writev, and one or more binaries. If these binaries should be retained,
when the driver returns from outputv, they can be queued (using driver_enq_bin for instance), or if they are kept in a
static or global variable, the reference counter can be incremented.

THIS IMPLEMENTATION of the callback unpacks a set of headers from the input binary and constructs a Command object
which is then submitted to the XslEngine. When the emulator is running in SMP mode, the actual processing is done on
an async thread (using the driver_async submission mechanism) and the apply_transform function is used to wrap the
XslEngine callback functions. The results of processing are handled on a main emulator thread in the ready_async driver callback.
*/
static void
outputv(ErlDrvData drv_data, ErlIOVec *ev) {

    // char *error_msg;
    char *xml;
    char *xsl;
    char *data;

    DriverHandle *d = (DriverHandle*)drv_data;
    ErlDrvPort port = (ErlDrvPort)d->port;
    InputSpec *hspec;
    PayloadSize *hsize;

    XslTask *job;
    DriverContext *ctx;
    AsyncState *asd;
    DriverState state;
    ErlDrvTermData callee_pid = driver_caller(port);
    UInt8 *type1;
    UInt64 *size;

    if ((hspec = ALLOC(sizeof(InputSpec))) == NULL) {
        FAIL(port, "system_limit");
        return;
    }
    if ((hsize = (PayloadSize*)try_driver_alloc(port,
        sizeof(PayloadSize), hspec)) == NULL) return;

    DBG("sizeof(uint64_t): %lu \n", sizeof(UInt64));
    DBG("ev->vsize: %i \n", ev->vsize);

    // the first 8bit chunk holds the number of parameters
    type1 = ((UInt8*)ev->binv[1]->orig_bytes);
    hspec->param_grp_arity = *type1;

    // next two 8bit chunks hold the type specs
    type1++;
    hspec->input_kind = *type1;

    type1++;
    hspec->xsl_kind = *type1;

    // next two 64bit chunks hold the type specs
    type1++;
    size = ((UInt64*)type1);
    hsize->input_size = *size;

    size++;
    hsize->xsl_size = *size;

    // next comes the xml and xslt binaries, which may be in one of three places:
    // 1. if the XML binary is heap allocated, it'll be in the binv entry
    // 2. if the XML binary is not heap allocated, it'll be in the next binv entry
    // 3. if the XSL binary is not heap allocated, it'll be in the next binv entry
    //        otherwise it'll bin in the (following) SysIOVec

    // if there is enough space remaining in a binv entry for the input document,
    // we pull it from there. Otherwise, it'll be collapsed into the first binary.
    size_t pos = ((sizeof(UInt8) * NUM_TYPE_HEADERS) +
                                (sizeof(UInt64) * NUM_SIZE_HEADERS));
    // INFO("pos = %lu \n", pos);
    UInt8 bin_idx = FIRST_BINV_ENTRY;    // first entry is reserved

    if ((pos + hsize->input_size) <= ev->binv[bin_idx]->orig_size) {
        data = (char*)(&ev->binv[bin_idx]->orig_bytes[pos]);
    } else {
        data = ev->binv[++bin_idx]->orig_bytes;
    }
    // FIXME: find a way around NULL terminated strings and we can share the binary!
    xml = ALLOC(hsize->input_size + 1);
    xml[hsize->input_size] = '\0';
    strncpy(xml, data, hsize->input_size);

    if (hsize->xsl_size < 64) {
        data = &ev->iov[++bin_idx].iov_base[0];
    } else {
        data = ev->binv[++bin_idx]->orig_bytes;
    }
    xsl = ALLOC(hsize->xsl_size + 1);
    xsl[hsize->xsl_size] = '\0';
    strncpy(xsl, data, hsize->xsl_size);

    if ((job = (XslTask*)try_driver_alloc(port,
        sizeof(XslTask), xml, xsl, hsize, hspec)) == NULL) return;
    if ((ctx = (DriverContext*)try_driver_alloc(port,
        sizeof(DriverContext), xml, xsl, hsize, hspec, job)) == NULL) return;
    if ((asd = (AsyncState*)try_driver_alloc(port,
        sizeof(AsyncState), xml, xsl, hsize, hspec, job, ctx)) == NULL) return;

    ctx->port = port;
    ctx->caller_pid = callee_pid;
    asd->driver = d;
    if ((asd->command = init_command(transform_command, ctx, job, NULL)) == NULL) {
        free_async_state(asd);
        FAIL(port, "system_limit");
        return;
    }

    fprintf(stderr, "xml[spec: %lu, len:%lu]\n", (long unsigned int)hsize->input_size, strlen(xml));
    fprintf(stderr, "xsl[spec: %lu, len:%lu]\n", (long unsigned int)hsize->xsl_size, strlen(xsl));

    state = init_task(job, hsize, hspec, xml, xsl);
    switch (state) {
    case OutOfMemoryError:
        free_async_state(asd);
        FAIL(port, "system_limit");
        return;
    case Success:
        /*
        driver_async will call engine->transform passing command, then
        call ready_async followed by cleanup_task. The synchronous code
        works something like this:

        (*a->async_invoke)(a->async_data);
        if (async_ready(prt, a->async_data)) {
            if (a->async_free != NULL)
                (*a->async_free)(a->async_data);
        }
        */
        INFO("provider handoff: transform\n");
        driver_async(port, NULL, apply_transform, asd, NULL); //cleanup_task);
        break;
    default:    // TODO: it would be better if we didn't do "everthing else is an error" here
        // TODO: error!?
        break;
    }
};
コード例 #16
0
ファイル: unixdom_drv.c プロジェクト: paulgray/unixdom_drv
static void s1_outputv(ErlDrvData drv_data, ErlIOVec *ev)
{
    descriptor_t        *desc = (descriptor_t *) drv_data;
    unsigned char       cmd;
    int                 p = 0, q = 1;
    callstate_t         *c = NULL;
    int                 do_async_call = default_async_calls;
    unsigned long       binlen;
    int                 index;
    void                *tmp = NULL;

    binlen = binlen;
    index = index;
    tmp = tmp;
    if (desc == NULL || ev == NULL || ev->size < 1) {
        edtk_debug("%s: bad arg(s)", __FUNCTION__);
        return;
    }
    if (! EV_GET_CHAR(ev, &cmd, &p, &q)) {
        edtk_debug("%s: empty command", __FUNCTION__);
        reply_error(desc, EINVAL);
    }
    if ((c = sys_alloc(sizeof(callstate_t))) == NULL) {
        reply_error(desc, ENOMEM);
        return;
    }
    c->cmd = cmd;
    c->key = NULL;
    c->free = sys_free;
    c->xid = 0;         /* XXX unused right now */
    c->o.__expect = 1;  /* Default is that expectation is always met */

    edtk_debug("%s: my threadid = %lx, cmd = %d", __FUNCTION__, pthread_self(), cmd);
    switch (cmd) {
    case S1_DEBUG:
        EV_GET_UINT32(ev, &edtk_debug_flag, &p, &q);
        reply_ok_num(desc, edtk_debug_flag);    /* Immediate reply */
        sys_free(c);
        c = NULL;
        break;
    case S1_NULL:
        c->invoke = invoke_s1_null;
        break;
    case S1_OPEN:
        c->invoke = invoke_s1_open;
        EV_GET_UINT32(ev, &binlen, &p, &q);
        c->i.filename = (char *) EV_GETPOS(ev, p, q);
        if (edtk_ev_forward_N(ev, binlen, &p, &q, 1) < 0) {
            goto error;
        }
        EV_GET_UINT32(ev, &c->i.flags, &p, &q);
        break;
    case S1_GETFD:
        c->invoke = invoke_s1_getfd;
        EV_GET_UINT32(ev, &index, &p, &q);
        if (desc->valmap_fd[index] == -1) {
            goto error;
        } else {
            edtk_debug("%s: valmap fd index %d = 0x%lx", __FUNCTION__, index, desc->valmap_fd[index]);
            c->i.fd = desc->valmap_fd[index];
            c->i.__valmap_fd_index = index;
        }
        break;
    case S1_SENDFD:
        c->invoke = invoke_s1_sendfd;
        EV_GET_UINT32(ev, &c->i.unixdom_fd, &p, &q);
        EV_GET_UINT32(ev, &c->i.fd_to_be_sent, &p, &q);
        break;
    case S1_RECEIVEFD:
        c->invoke = invoke_s1_receivefd;
        EV_GET_UINT32(ev, &c->i.unixdom_fd, &p, &q);
        break;
    case S1_CLOSE:
        c->invoke = invoke_s1_close;
        EV_GET_UINT32(ev, &index, &p, &q);
        if (index == -1 && 0 == 1) {
            edtk_debug("%s: valmap fd index %d = default value 0x%lx", __FUNCTION__, index, -1);
            c->i.fd = -1;
            c->i.__valmap_fd_index = -1;
        } else if (desc->valmap_fd[index] == -1) {
            goto error;
        } else {
            edtk_debug("%s: valmap fd index %d = 0x%lx", __FUNCTION__, index, desc->valmap_fd[index]);
            c->i.fd = desc->valmap_fd[index];
            c->i.__valmap_fd_index = index;
        }
        break;
    }

    if (c != NULL) {
        if (do_async_call) {
            driver_async(desc->port, c->key, c->invoke, c, c->free);
        } else {
            /*
            ** Execute the bottom half right away, then send the result.
            */
            (*(c->invoke))((void *) c);
            s1_ready_async((ErlDrvData) desc, (ErlDrvThreadData) c);
            /*
            ** c is already freed for us by s1_ready_async()
            */
        }
    }
    return;

  error:
    if (c != NULL) {
        sys_free(c);
    }
    reply_error_atom(desc, am_badarg);
}