Пример #1
0
v8::Handle<v8::Value> Open(const v8::Arguments& args) {
  v8::HandleScope scope;

  uv_mutex_init(&write_queue_mutex);
  ngx_queue_init(&write_queue);

  // path
  if(!args[0]->IsString()) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument must be a string"))));
  }
  v8::String::Utf8Value path(args[0]->ToString());

  // options
  if(!args[1]->IsObject()) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("Second argument must be an object"))));
  }
  v8::Local<v8::Object> options = args[1]->ToObject();

  // callback
  if(!args[2]->IsFunction()) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("Third argument must be a function"))));
  }
  v8::Local<v8::Value> callback = args[2];

  OpenBaton* baton = new OpenBaton();
  memset(baton, 0, sizeof(OpenBaton));
  strcpy(baton->path, *path);
  baton->baudRate = options->Get(v8::String::New("baudRate"))->ToInt32()->Int32Value();
  baton->dataBits = options->Get(v8::String::New("dataBits"))->ToInt32()->Int32Value();
  baton->bufferSize = options->Get(v8::String::New("bufferSize"))->ToInt32()->Int32Value();
  baton->parity = ToParityEnum(options->Get(v8::String::New("parity"))->ToString());
  baton->stopBits = ToStopBitEnum(options->Get(v8::String::New("stopBits"))->ToNumber()->NumberValue());
  baton->flowControl = options->Get(v8::String::New("flowControl"))->ToBoolean()->BooleanValue();
  baton->callback = v8::Persistent<v8::Value>::New(callback);
  baton->dataCallback = v8::Persistent<v8::Value>::New(options->Get(v8::String::New("dataCallback")));
  baton->disconnectedCallback = v8::Persistent<v8::Value>::New(options->Get(v8::String::New("disconnectedCallback")));
  baton->errorCallback = v8::Persistent<v8::Value>::New(options->Get(v8::String::New("errorCallback")));

  uv_work_t* req = new uv_work_t();
  req->data = baton;
  uv_queue_work(uv_default_loop(), req, EIO_Open, (uv_after_work_cb)EIO_AfterOpen);

  return scope.Close(v8::Undefined());
}
Пример #2
0
v8::Handle<v8::Value> List(const v8::Arguments& args) {
  v8::HandleScope scope;

  // callback
  if(!args[0]->IsFunction()) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument must be a function"))));
  }
  v8::Local<v8::Value> callback = args[0];

  ListBaton* baton = new ListBaton();
  strcpy(baton->errorString, "");
  baton->callback = v8::Persistent<v8::Value>::New(callback);

  uv_work_t* req = new uv_work_t();
  req->data = baton;
  uv_queue_work(uv_default_loop(), req, EIO_List, EIO_AfterList);

  return scope.Close(v8::Undefined());
}
Пример #3
0
static void assert_run_work(uv_loop_t* const loop) {
  uv_work_t work_req;
  int r;

  ASSERT(work_cb_count == 0);
  ASSERT(after_work_cb_count == 0);
  printf("Queue in %d\n", getpid());
  r = uv_queue_work(loop, &work_req, work_cb, after_work_cb);
  ASSERT(r == 0);
  printf("Running in %d\n", getpid());
  uv_run(loop, UV_RUN_DEFAULT);

  ASSERT(work_cb_count == 1);
  ASSERT(after_work_cb_count == 1);

  /* cleanup  */
  work_cb_count = 0;
  after_work_cb_count = 0;
}
Пример #4
0
v8::Handle<v8::Value> Func(const v8::Arguments& args)
{
	v8::HandleScope scope;
    if (args.Length() < 2) {
        return ThrowException(v8::Exception::TypeError(v8::String::New("Must provide a callback")));
    }

    v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
    std::string toSayNonV8 = std::string(*v8::String::Utf8Value(args[0]));

    Baton* baton = new Baton();
    baton->request.data = baton;
    baton->toSay = toSayNonV8;
    baton->callback = v8::Persistent<v8::Function>::New(callback);


    int status = uv_queue_work(uv_default_loop(), &baton->request, Work, After);
    assert(status == 0);
    return v8::Undefined();
}
Пример #5
0
void
on_read(uv_stream_t* server, ssize_t nread, const uv_buf_t *buf) {  

  member *memb = (member*)server->data;

  if (nread == EOF){
    uv_close((uv_handle_t*)memb->server, on_close);
    fprintf(stderr, "nothing read\n");
    return;
  }

  assume_buffer(memb, buf->base, nread);

  int status = uv_queue_work(
    loop,
    &memb->work,
    read_work,
    (uv_after_work_cb)read_after);
  assert(status == 0);   
}
Пример #6
0
Handle<Value> Engine::run(Arguments const& args)
{
    HandleScope scope;

    if (args.Length() == 1) {
        return runSync(args);
    }

    if (args.Length() < 1) {
        ThrowException(String::New("first argument must be a osrm.Query"));
    }

    if (!args[0]->IsObject()) {
        return ThrowException(String::New("first argument must be a osrm.Query object"));
    }

    Local<Object> obj = args[0]->ToObject();
    if (obj->IsNull() || obj->IsUndefined() || !Query::constructor->HasInstance(obj)) {
        ThrowException(Exception::TypeError(String::New("osrm.Query object expected for first argument")));
    }

    // ensure callback is a function
    Local<Value> callback = args[args.Length()-1];
    if (!args[args.Length()-1]->IsFunction()) {
        return ThrowException(Exception::TypeError(
                                  String::New("last argument must be a callback function")));
    }

    Query * query = ObjectWrap::Unwrap<Query>(obj);
    Engine * machine = ObjectWrap::Unwrap<Engine>(args.This());
    run_query_baton_t *closure = new run_query_baton_t();
    closure->request.data = closure;
    closure->machine = machine;
    closure->query = query;
    closure->error = false;
    closure->cb = Persistent<Function>::New(Handle<Function>::Cast(callback));
    uv_queue_work(uv_default_loop(), &closure->request, AsyncRun, (uv_after_work_cb)AfterRun);
    closure->machine->_ref();
    closure->query->_ref();
    return Undefined();
}
Пример #7
0
Handle<Value> Image::composite(const Arguments& args)
{
    HandleScope scope;

    if (args.Length() < 2){
        return ThrowException(Exception::TypeError(
                                  String::New("requires two arguments: an image mask and a compositeOp")));
    }

    if (!args[0]->IsObject()) {
        return ThrowException(Exception::TypeError(
                                  String::New("first argument must be an image mask")));
    }

    if (!args[1]->IsNumber()) {
        return ThrowException(Exception::TypeError(
                                  String::New("second argument must be an compositeOp value")));
    }

    Local<Object> im2 = args[0]->ToObject();
    if (im2->IsNull() || im2->IsUndefined() || !Image::constructor->HasInstance(im2))
        return ThrowException(Exception::TypeError(String::New("mapnik.Image expected as first arg")));

    // ensure callback is a function
    Local<Value> callback = args[args.Length()-1];
    if (!args[args.Length()-1]->IsFunction())
        return ThrowException(Exception::TypeError(
                                  String::New("last argument must be a callback function")));

    composite_image_baton_t *closure = new composite_image_baton_t();
    closure->request.data = closure;
    closure->im1 = ObjectWrap::Unwrap<Image>(args.This());
    closure->im2 = ObjectWrap::Unwrap<Image>(im2);
    closure->mode = static_cast<mapnik::composite_mode_e>(args[1]->IntegerValue());
    closure->error = false;
    closure->cb = Persistent<Function>::New(Handle<Function>::Cast(callback));
    uv_queue_work(uv_default_loop(), &closure->request, EIO_Composite, EIO_AfterComposite);
    closure->im1->Ref();
    closure->im2->Ref();
    return Undefined();
}
Пример #8
0
/**
 * @details This is an asynchronous factory method creating a new `Map`
 * instance from a string representation of a mapserver mapfile.
 *
 * `args` should contain the following parameters:
 *
 * @param mapfile A string representing the mapfile.
 *
 * @param callback A function that is called on error or when the map has been
 * created. It should have the signature `callback(err, map)`.
 */
Handle<Value> Map::FromStringAsync(const Arguments& args) {
  HandleScope scope;
  string mapfile;

  if (args.Length() != 2) {
    THROW_CSTR_ERROR(Error, "usage: Map.FromString(mapfile, callback)");
  }

  // get the mapfile string from the arguments
  if (args[0]->IsString()) {
    mapfile = *String::Utf8Value(args[0]->ToString());
  } else if (args[0]->IsObject()) {
    // see if it's a buffer
    if (!Buffer::HasInstance(args[0])) {
      THROW_CSTR_ERROR(TypeError, "Argument 0 must be a string or buffer");
    }
    Local<Object> buffer = args[0]->ToObject();
    mapfile = string(Buffer::Data(buffer), Buffer::Length(buffer));
  } else {
    THROW_CSTR_ERROR(TypeError, "Argument 0 must be a string or buffer");
  }

  REQ_FUN_ARG(1, callback);

  MapfileBaton *baton = new MapfileBaton();
  baton->request.data = baton;
  baton->map = NULL;
  baton->callback = Persistent<Function>::New(callback);
  baton->error = NULL;
  baton->mapfile = mapfile;

  // Run in a different thread. Note there is *no* `FromStringAfter`:
  // `FromFileAfter` is used instead.
  uv_queue_work(uv_default_loop(),
                &baton->request,
                FromStringWork,
                (uv_after_work_cb) FromFileAfter);

  return Undefined();
}
Пример #9
0
static int luv_queue_work(lua_State* L) {
  int top = lua_gettop(L);
  luv_work_ctx_t* ctx = luv_check_work_ctx(L, 1);
  luv_work_t* work = malloc(sizeof(*work));
  int ret;

  luv_thread_arg_set(L, &work->arg, 2, top);
  work->ctx = ctx;
  work->work.data = work;
  ret = uv_queue_work(luv_loop(L), &work->work, luv_work_cb, luv_after_work_cb);
  if (ret < 0) {
    free(work);
    return luv_error(L, ret);
  }

  //ref up to ctx 
  lua_pushlightuserdata(L, work);
  lua_pushvalue(L, 1);
  lua_rawset(L, LUA_REGISTRYINDEX);

  lua_pushboolean(L, 1);
  return 1;
}
Пример #10
0
v8::Handle<v8::Value> Write(const v8::Arguments& args) {
  v8::HandleScope scope;

  // file descriptor
  if(!args[0]->IsInt32()) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument must be an int"))));
  }
  int fd = args[0]->ToInt32()->Int32Value();

  // buffer
  if(!args[1]->IsObject() || !node::Buffer::HasInstance(args[1])) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("Second argument must be a buffer"))));
  }
  v8::Persistent<v8::Object> buffer = v8::Persistent<v8::Object>::New(args[1]->ToObject());
  char* bufferData = node::Buffer::Data(buffer);
  size_t bufferLength = node::Buffer::Length(buffer);

  // callback
  if(!args[2]->IsFunction()) {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("Third argument must be a function"))));
  }
  v8::Local<v8::Value> callback = args[2];

  WriteBaton* baton = new WriteBaton();
  memset(baton, 0, sizeof(WriteBaton));
  baton->fd = fd;
  baton->buffer = buffer;
  baton->bufferData = bufferData;
  baton->bufferLength = bufferLength;
  baton->callback = v8::Persistent<v8::Value>::New(callback);

  uv_work_t* req = new uv_work_t();
  req->data = baton;
  uv_queue_work(uv_default_loop(), req, EIO_Write, EIO_AfterWrite);

  return scope.Close(v8::Undefined());
}
Пример #11
0
        static v8::Handle<v8::Value> call(v8::Arguments const& args)
        {
            typedef Worker Instance::* member_ptr_t;
        
            v8::HandleScope scope;
        
            // get member pointer
            uint32_t member_ptr_value = args.Data()->NumberValue();
            member_ptr_t member_ptr = *reinterpret_cast<member_ptr_t *>(&member_ptr_value);
            
            // get instance
            Instance & instance = get_wrapped_object<Instance>(args);
            
            // get derived worker ref
            Worker & worker = instance.*member_ptr;
            
            // get the work request
            uv_work_t * work_req = worker.get_work_request();
            if (!work_req)
            {
                // error in arguments, return undefined
                return scope.Close(v8::Undefined());
            }

            // store the arguments
            worker.store_arguments(args);

            // queue work function
            work_req->data = &worker;
            uv_queue_work(uv_default_loop(),
                          work_req,
                          &worker_base::process_impl<Instance, Worker>,
                          &worker_base::after_impl<Instance, Worker>);
            
            return scope.Close(v8::Undefined());
        }
Пример #12
0
uni::CallbackType OracleClient::Connect(const uni::FunctionCallbackInfo& args) {
  UNI_SCOPE(scope);

  REQ_OBJECT_ARG(0, settings);
  REQ_FUN_ARG(1, callback);

  OracleClient* client = ObjectWrap::Unwrap<OracleClient>(args.This());
  ConnectBaton* baton = new ConnectBaton(client, client->m_environment, &callback);

  OBJ_GET_STRING(settings, "hostname", baton->hostname);
  OBJ_GET_STRING(settings, "user", baton->user);
  OBJ_GET_STRING(settings, "password", baton->password);
  OBJ_GET_STRING(settings, "database", baton->database);
  OBJ_GET_NUMBER(settings, "port", baton->port, 1521);
  OBJ_GET_STRING(settings, "tns", baton->tns);

  client->Ref();

  uv_work_t* req = new uv_work_t();
  req->data = baton;
  uv_queue_work(uv_default_loop(), req, EIO_Connect, (uv_after_work_cb)EIO_AfterConnect);

  UNI_RETURN(scope, args, NanUndefined());
}
Пример #13
0
static void do_newuser(MyMSG* msg, CMsgSocket* s)
{
    printf("received new user: id: %d; room: %d\n", msg->body.userinfo.userid, msg->body.userinfo.roomid);
    s->dis_connect();
	cnt++;
	if (cnt > 6){
		s1->dis_connect();
		s2->dis_connect();
		return;
	}
    CMsgSocket* s11 = dynamic_cast<CMsgSocket*>(CResourcePool::GetInstance()->Get(e_rsc_msgsocket));
	if (s == s1) s1 = s11;
	else s2 = s11;
	cc_userinfo_t userinfo = { 0 };
	userinfo.roomid = msg->body.userinfo.roomid;
	userinfo.userid = !msg->body.userinfo.userid;
	s11->set_local_user(&userinfo);
	s11->on_received(s11, on_msg);
	s11->on_received_frame(s11, on_frame);
    uv_work_t* req = (uv_work_t*)malloc(sizeof(uv_work_t));
    req->data = s11;
    int ret = uv_queue_work(uv_default_loop(), req, do_nothing, reconn);
    printf("queue reconn return %d\n", ret);
}
Пример #14
0
/**
 * @details This is an asynchronous factory method creating a new `Map`
 * instance from a mapserver mapfile.
 *
 * `args` should contain the following parameters:
 *
 * @param mapfile A string representing the mapfile path.
 *
 * @param callback A function that is called on error or when the map has been
 * created. It should have the signature `callback(err, map)`.
 */
Handle<Value> Map::FromFileAsync(const Arguments& args) {
  HandleScope scope;

  if (args.Length() != 2) {
    THROW_CSTR_ERROR(Error, "usage: Map.FromFile(mapfile, callback)");
  }
  REQ_STR_ARG(0, mapfile);
  REQ_FUN_ARG(1, callback);

  MapfileBaton *baton = new MapfileBaton();

  baton->request.data = baton;
  baton->map = NULL;
  baton->callback = Persistent<Function>::New(callback);
  baton->error = NULL;
  baton->mapfile = *mapfile;

  uv_queue_work(uv_default_loop(),
                &baton->request,
                FromFileWork,
                (uv_after_work_cb) FromFileAfter);

  return Undefined();
}
Пример #15
0
//call client signal callback
static void 
signal_cb (std::string subscriber_name,
	   std::string quiddity_name, 
	   std::string signal_name, 
	   std::vector<std::string> params, 
	   void *user_data)
{
  if (g_strcmp0 (signal_name.c_str (), "on-quiddity-created") == 0
      && switcher_is_loading == false)
    g_thread_create (set_runtime_invoker, 
		     g_strdup (params[0].c_str ()),
		     FALSE,
		     NULL);
  
  async_req_signal *req = new async_req_signal ();
  req->req.data = req;
  req->quiddity_name = quiddity_name;
  req->signal_name = signal_name;
  req->params = params;
  uv_queue_work (uv_default_loop(),
		 &req->req,
		 DoNothingAsync,
		 (uv_after_work_cb)NotifySignal);
}
Handle<Value> OracleClient::Connect(const Arguments& args) {
  HandleScope scope;

  REQ_OBJECT_ARG(0, settings);
  REQ_FUN_ARG(1, callback);

  OracleClient* client = ObjectWrap::Unwrap<OracleClient>(args.This());
  ConnectBaton* baton = new ConnectBaton(client, client->m_environment, &callback);

  OBJ_GET_STRING(settings, "hostname", baton->hostname);
  OBJ_GET_STRING(settings, "user", baton->user);
  OBJ_GET_STRING(settings, "password", baton->password);
  OBJ_GET_STRING(settings, "database", baton->database);
  OBJ_GET_NUMBER(settings, "port", baton->port, 1521);
  OBJ_GET_STRING(settings, "tns", baton->tns);

  client->Ref();

  uv_work_t* req = new uv_work_t();
  req->data = baton;
  uv_queue_work(uv_default_loop(), req, EIO_Connect, (uv_after_work_cb)EIO_AfterConnect);

  return scope.Close(Undefined());
}
Пример #17
0
int CVideoDecoder2::Init(void)
{
	int ret = -1;
	while (!bInit){
        pQueueMutex = (uv_mutex_t*)malloc(sizeof(uv_mutex_t));
        if(!pQueueMutex){
			ret = -1;
			break;
		}
        ret = uv_mutex_init(pQueueMutex);
		if (ret < 0){
            free(pQueueMutex);
            pQueueMutex = NULL;
			break;
		}
        pQueueNotEmpty = (uv_cond_t*)malloc(sizeof(uv_cond_t));
        if(!pQueueNotEmpty){
			ret = -1;
			break;
		}
        ret = uv_cond_init(pQueueNotEmpty);
		if (ret < 0){
            free(pQueueNotEmpty);
            pQueueNotEmpty = NULL;
			break;
		}

		// Register all codecs
		avcodec_register_all();
		pCodec = avcodec_find_decoder(codecId);
		if (!pCodec){
			ret = -1;
			break;
		}
		pCodecCtx = avcodec_alloc_context3(pCodec);
		if (!pCodecCtx){
			ret = -1;
			break;
		}
		if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){
			ret = -1;
			break;
		}

		pCodecParserCtx = av_parser_init(codecId);
		if (!pCodecParserCtx){
			ret = -1;
			break;
		}
        decodeWorkerReq.data = this;
        ret = uv_queue_work(pLoop, &decodeWorkerReq, DecodeWorker, AfterDecode);
        if(ret < 0){
            bStop = true;
            break;
        }
		bInit = true;
	}
	if (!bInit){
		Finit();
		return -1;
	} else {
		return 0;
	}
}
Пример #18
0
void InitDetection() 
{

    kern_return_t           kr;

    // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow
    // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7.
    // See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X" 
    // <http://developer.apple.com/qa/qa2001/qa1076.html>.
    // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching 
    // criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will 
    // consume this dictionary reference, so there is no need to release it later on.
    
    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);    // Interested in instances of class
                                                                // IOUSBDevice and its subclasses
    
    if (matchingDict == NULL) 
    {
        fprintf(stderr, "IOServiceMatching returned NULL.\n");
    }

    // Create a notification port and add its run loop event source to our run loop
    // This is how async notifications get set up.
    
    gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);

    // Now set up a notification to be called when a device is first matched by I/O Kit.
    kr = IOServiceAddMatchingNotification(gNotifyPort,                  // notifyPort
                                          kIOFirstMatchNotification,    // notificationType
                                          matchingDict,                 // matching
                                          DeviceAdded,                  // callback
                                          NULL,                         // refCon
                                          &gAddedIter                   // notification
                                          );        
    
    if (KERN_SUCCESS != kr) 
    {
        printf("IOServiceAddMatchingNotification returned 0x%08x.\n", kr);
    }

    // Iterate once to get already-present devices and arm the notification
    DeviceAdded(NULL, gAddedIter);
    intialDeviceImport = false;


    pthread_mutex_init(&notify_mutex, NULL);
    pthread_cond_init(&notifyNewDevice, NULL);
    pthread_cond_init(&notifyDeviceHandled, NULL);

    int rc = pthread_create(&lookupThread, NULL, RunLoop, NULL);
    if (rc)
    {
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
    }

    uv_work_t* req = new uv_work_t();
    uv_queue_work(uv_default_loop(), req, NotifyAsync, (uv_after_work_cb)NotifyFinished);
    
    Start();
}
Пример #19
0
static void eventpool_execute(uv_async_t *handle) {
	/*
	 * Make sure we execute in the main thread
	 */
	const uv_thread_t pth_cur_id = uv_thread_self();
	assert(uv_thread_equal(&pth_main_id, &pth_cur_id));

	struct threadpool_tasks_t **node = NULL;
	int nrlisteners1[REASON_END] = {0};
	int nr1 = 0, nrnodes = 16, nrnodes1 = 0, i = 0;

	if((node = MALLOC(sizeof(struct threadpool_tasks_t *)*nrnodes)) == NULL) {
		OUT_OF_MEMORY /*LCOV_EXCL_LINE*/
	}

	uv_mutex_lock(&listeners_lock);

	struct eventqueue_t *queue = NULL;
	while(eventqueue) {
		queue = eventqueue;
		uv_sem_t *ref = NULL;

#ifdef _WIN32
		if((nr1 = InterlockedExchangeAdd(&nrlisteners[queue->reason], 0)) == 0) {
#else
		if((nr1 = __sync_add_and_fetch(&nrlisteners[queue->reason], 0)) == 0) {
#endif
			if(queue->done != NULL) {
				queue->done((void *)queue->data);
			}
		} else {
			if(threads == EVENTPOOL_THREADED) {
				if((ref = MALLOC(sizeof(uv_sem_t))) == NULL) {
					OUT_OF_MEMORY /*LCOV_EXCL_LINE*/
				}
				uv_sem_init(ref, nr1-1);
			}

			struct eventpool_listener_t *listeners = eventpool_listeners;
			if(listeners == NULL) {
				if(queue->done != NULL) {
					queue->done((void *)queue->data);
				}
			}

			while(listeners) {
				if(listeners->reason == queue->reason) {
					if(nrnodes1 == nrnodes) {
						nrnodes *= 2;
						/*LCOV_EXCL_START*/
						if((node = REALLOC(node, sizeof(struct threadpool_tasks_t *)*nrnodes)) == NULL) {
							OUT_OF_MEMORY
						}
						/*LCOV_EXCL_STOP*/
					}
					if((node[nrnodes1] = MALLOC(sizeof(struct threadpool_tasks_t))) == NULL) {
						OUT_OF_MEMORY /*LCOV_EXCL_LINE*/
					}
					node[nrnodes1]->func = listeners->func;
					node[nrnodes1]->userdata = queue->data;
					node[nrnodes1]->done = queue->done;
					node[nrnodes1]->ref = ref;
					node[nrnodes1]->reason = listeners->reason;
					nrnodes1++;
					if(threads == EVENTPOOL_THREADED) {
						nrlisteners1[queue->reason]++;
					}
				}
				listeners = listeners->next;
			}
		}
		eventqueue = eventqueue->next;
		FREE(queue);
	}
	uv_mutex_unlock(&listeners_lock);

	if(nrnodes1 > 0) {
		for(i=0;i<nrnodes1;i++) {
			if(threads == EVENTPOOL_NO_THREADS) {
				nrlisteners1[node[i]->reason]++;
				node[i]->func(node[i]->reason, node[i]->userdata);

#ifdef _WIN32
				if(nrlisteners1[node[i]->reason] == InterlockedExchangeAdd(&nrlisteners[node[i]->reason], 0)) {
#else
				if(nrlisteners1[node[i]->reason] == __sync_add_and_fetch(&nrlisteners[node[i]->reason], 0)) {
#endif
					if(node[i]->done != NULL) {
						node[i]->done((void *)node[i]->userdata);
					}
					nrlisteners1[node[i]->reason] = 0;
				}
			} else {
				struct threadpool_data_t *tpdata = NULL;
				tpdata = MALLOC(sizeof(struct threadpool_data_t));
				if(tpdata == NULL) {
					OUT_OF_MEMORY /*LCOV_EXCL_LINE*/
				}
				tpdata->userdata = node[i]->userdata;
				tpdata->func = node[i]->func;
				tpdata->done = node[i]->done;
				tpdata->ref = node[i]->ref;
				tpdata->reason = node[i]->reason;
				tpdata->priority = reasons[node[i]->reason].priority;

				uv_work_t *tp_work_req = MALLOC(sizeof(uv_work_t));
				if(tp_work_req == NULL) {
					OUT_OF_MEMORY /*LCOV_EXCL_LINE*/
				}
				tp_work_req->data = tpdata;
				if(uv_queue_work(uv_default_loop(), tp_work_req, reasons[node[i]->reason].reason, fib, fib_free) < 0) {
					if(node[i]->done != NULL) {
						node[i]->done((void *)node[i]->userdata);
					}
					FREE(tpdata);
					FREE(node[i]->ref);
				}
			}
			FREE(node[i]);
		}
	}
	for(i=0;i<REASON_END;i++) {
		nrlisteners1[i] = 0;
	}
	FREE(node);
	uv_mutex_lock(&listeners_lock);
	if(eventqueue != NULL) {
		uv_async_send(async_req);
	}
	uv_mutex_unlock(&listeners_lock);
}
Пример #20
0
void Future::run_callback_on_work_thread() {
  inc_ref(); // Keep the future alive for the callback
  work_.data = this;
  uv_queue_work(loop_.load(), &work_, on_work, on_after_work);
}
Пример #21
0
/**
 * handle queues. this handles all deletions of callbacks as well as setting up the uv requests on each cycle. In normal course of affairs, it will be locked
 * for operation, as should all the queue vectors for all the various requests
 */
void
UVEventLoop::HandleRunnerQueues()
{
	for (auto bit = resolvers.begin(); bit != resolvers.end();) {
		auto qp = *bit;
		if (qp->disposed) {
			if (qp->bindCB) delete qp->bindCB;
			delete qp;
			bit = resolvers.erase(bit);
		} else if (!qp->resolving) {
			qp->resolving = true;
			qp->dnsHints.ai_family = PF_INET;
			qp->dnsHints.ai_socktype = SOCK_STREAM;
			qp->dnsHints.ai_protocol = IPPROTO_TCP;
			qp->dnsHints.ai_flags = 0;
			qp->resolver.data = qp;
			UVTCPClient* client = const_cast<UVTCPClient*>(qp->client);
			if (client->address == nullptr || client->socket == nullptr) {

			}
			int r = uv_getaddrinfo(
					loop, &qp->resolver, OnResolved,
					qp->host.c_str(), qp->service.c_str(), &qp->dnsHints);
			if (r<0) {
				if (qp->bindCB) {
					(*qp->bindCB)(client->address, kUVBindCallError);
				}
				qp->disposed = true;
			}
			++bit;
		} else {
			++bit;
		}
	}
	for (auto rit = readers.begin(); rit != readers.end();) {
		auto qp = *rit;
		if (qp->disposed) {
//! in the main connection queue, readers, the socket i.e. client has ownership of the read callback (*rit)->cb that should be erased by the close request, which will
//! supplant the read functional call back with a close functional
			if (qp->connectCB) delete qp->connectCB;
			if (qp->readerCB) delete qp->readerCB;
			if (qp->closerCB) delete qp->closerCB;
			delete qp;
			rit = readers.erase(rit);
		} else if (qp->closing) {
			UVTCPClient* client = const_cast<UVTCPClient*>(qp->client);
			int r = uv_read_stop((uv_stream_t*)client->socket);
			if (r >= 0) {
				uv_close((uv_handle_t*)client->socket, OnClose);
			}
			qp->closing = false; // only try to close once!
			++rit;
		} else if (!qp->connected) {
			qp->connected = true;
			UVTCPClient *client = const_cast<UVTCPClient*>(qp->client);
			if (client->socket) {
				if (client->socket->data) { // should already be deleted
				}
				uv_tcp_init(loop, client->socket);
				client->socket->data = qp;
				qp->request.data = qp;
				int r=uv_tcp_connect(&qp->request, client->socket, client->address, OnConnect);
				if (r<0) {
					if (qp->connectCB) {
						(*qp->connectCB)(&qp->request, kUVCnxCallError);
					}
				}
			}
			++rit;
		} else {
			++rit;
		}
	}
	for (auto writ = writers.begin(); writ != writers.end();) {
		auto qp=*writ;
		if (qp->disposed) {
			if (qp->buf.base) {
				delete []qp->buf.base;
			}
			delete *writ;
			writ = writers.erase(writ);
		} else {
			UVTCPClient* client = const_cast<UVTCPClient*>((*writ)->client);
			int r=uv_write(&qp->request, (uv_stream_t*)client->socket, &qp->buf, 1, OnWrite);
			if (r < 0) {
				qp->disposed = true;
			}
			++writ;
		}
	}
	;
	for (auto cit = closers.begin(); cit != closers.end();) {
		auto qp = *cit;
		if (qp->disposed) {
			if (qp->cb) delete qp->cb;
			delete qp;
			cit=closers.erase(cit);
		} else {
			UVTCPClient* client = const_cast<UVTCPClient*>(qp->client);
			uv_read_stop((uv_stream_t*)client->socket);
			if (client->socket->data) {
				delete static_cast<ReaderCB*>(client->socket->data);
			}
			client->socket->data = qp;
			uv_close((uv_handle_t*)client->socket, OnClose);
			++cit;
		}
	}
//	workerLock.lock();
	for (auto wit = activeWorkers.begin(); wit != activeWorkers.end();) {
		auto qp=*wit;
		if (qp->disposed) {
			if (qp->queuedCB) delete qp->queuedCB;
			if (qp->apresCB) delete qp->apresCB;
			delete qp;
			wit = activeWorkers.erase(wit);
		} else {
			int r = uv_queue_work(loop, &qp->work, OnWork, OnAfterWork);
			if (r < 0) {
				OnAfterWork(&qp->work, r);
			}
			++wit;
		}
	}
//	workerLock.unlock();
	for (auto tit = scheduledTimers.begin(); tit != scheduledTimers.end();) {
		auto qp = *tit;
		if (qp->disposed) {
			if (qp->tikCB) delete qp->tikCB;
			delete qp;
		} else {
			DEBUG_OUT("UVEventLoop::HandleRunnerQueues() timer started");
			uv_timer_init(loop, &qp->timer);
			uv_timer_start(&qp->timer, OnTick, qp->delayMS, qp->repeatMs);
			activeTimers.push_back(qp);
		}
		tit = scheduledTimers.erase(tit);
	}
	for (auto tit = activeTimers.begin(); tit != activeTimers.end();) {
		auto qp = *tit;
		if (qp->disposed) {
			DEBUG_OUT("UVEventLoop::HandleRunnerQueues() timer cleaned up");
			if (uv_is_active((uv_handle_t*)&qp->timer)) {
				DEBUG_OUT("UVEventLoop::HandleRunnerQueues() stopping an active timer");
				uv_timer_stop(&qp->timer);
				++tit;
			} else {
				if (qp->tikCB) delete qp->tikCB;
				delete qp;
				tit = activeTimers.erase(tit);
			}
		} else {
			++tit;
		}
	}
}
Пример #22
0
void MethodCallBaton::run() {
  uv_work_t* req = new uv_work_t();
  req->data = this;
  uv_queue_work(uv_default_loop(), req, MethodCallBaton::EIO_MethodCall, (uv_after_work_cb)MethodCallBaton::EIO_AfterMethodCall);
}
Пример #23
0
Handle<Value> Grid::encode(const Arguments& args) // format, resolution
{
    HandleScope scope;

    Grid* g = ObjectWrap::Unwrap<Grid>(args.This());

    // defaults
    std::string format("utf");
    unsigned int resolution = 4;
    bool add_features = true;

    // accept custom format
    if (args.Length() >= 1){
        if (!args[0]->IsString())
            return ThrowException(Exception::TypeError(
                                      String::New("first arg, 'format' must be a string")));
        format = TOSTR(args[0]);
    }

    // options hash
    if (args.Length() >= 2) {
        if (!args[1]->IsObject())
            return ThrowException(Exception::TypeError(
                                      String::New("optional second arg must be an options object")));

        Local<Object> options = args[1]->ToObject();

        if (options->Has(String::New("resolution")))
        {
            Local<Value> bind_opt = options->Get(String::New("resolution"));
            if (!bind_opt->IsNumber())
                return ThrowException(Exception::TypeError(
                                          String::New("'resolution' must be an Integer")));

            resolution = bind_opt->IntegerValue();
        }

        if (options->Has(String::New("features")))
        {
            Local<Value> bind_opt = options->Get(String::New("features"));
            if (!bind_opt->IsBoolean())
                return ThrowException(Exception::TypeError(
                                          String::New("'features' must be an Boolean")));

            add_features = bind_opt->BooleanValue();
        }
    }

    // ensure callback is a function
    if (!args[args.Length()-1]->IsFunction())
        return ThrowException(Exception::TypeError(
                                  String::New("last argument must be a callback function")));
    Local<Function> callback = Local<Function>::Cast(args[args.Length()-1]);

    encode_grid_baton_t *closure = new encode_grid_baton_t();
    closure->request.data = closure;
    closure->g = g;
    closure->format = format;
    closure->error = false;
    closure->resolution = resolution;
    closure->add_features = add_features;
    closure->cb = Persistent<Function>::New(Handle<Function>::Cast(callback));
    // todo - reserve lines size?
    uv_queue_work(uv_default_loop(), &closure->request, EIO_Encode, EIO_AfterEncode);
    g->Ref();
    return Undefined();
}
Пример #24
0
 static void uvwork(void *ctx) {
     uv_work_t* req = new uv_work_t;
     req->data = ctx;
     uv_queue_work(uv_default_loop(), req, nop, v8isr);
 }
Пример #25
0
static void push_work_queue( strus_connection_t* conn)
{
	memset( &conn->work_req, 0, sizeof(conn->work_req));
	conn->work_req.data = (void*)conn;
	uv_queue_work( g_server.loop, &conn->work_req, on_work, on_complete_work);
}
Пример #26
0
static int curl(lua_State *L) {
	uv_loop_t *loop = (uv_loop_t *)lua_touserptr(L, lua_upvalueindex(1));

	luv_curl_t *lc = (luv_curl_t *)lua_newuserdata(L, sizeof(luv_curl_t));
	memset(lc, 0, sizeof(luv_curl_t));
	int lc_idx = 2;

	lc->loop = loop;
	lc->L = L;

	lua_getfield(L, 1, "url");
	char *url = (char *)lua_tostring(L, -1);
	if (url == NULL) 
		panic("url must be set");

	lua_getfield(L, 1, "retry");
	lc->retry = lua_tonumber(L, -1);

	lua_getfield(L, 1, "retfile");
	char *retfname = (char *)lua_tostring(L, -1);
	if (retfname)
		lc->retfname = strdup(retfname);
	else
		lc->retsb = strbuf_new(2048);

	if (lc->retfname) {
		lc->retfp = fopen(lc->retfname, "wb+");
		info("'%s' opened", lc->retfname);
		if (lc->retfp == NULL) {
			warn("open '%s' failed", lc->retfname);
			lc->stat = ERROR;
			lc->err = "open_file_failed";
		}
	}

	lc->c = curl_easy_init();

	curl_easy_setopt(lc->c, CURLOPT_URL, url);
	curl_easy_setopt(lc->c, CURLOPT_WRITEFUNCTION, write_data);
	curl_easy_setopt(lc->c, CURLOPT_WRITEDATA, lc);

	curl_easy_setopt(lc->c, CURLOPT_SSL_VERIFYPEER, 0);

	//curl_easy_setopt(lc->c, CURLOPT_VERBOSE, 1);

	lua_getfield(L, 1, "reqstr");
	lc->reqstr = (char *)lua_tostring(L, -1);
	if (lc->reqstr) {
		//lc->reqstr_len = strlen(lc->reqstr);
		//curl_easy_setopt(lc->c, CURLOPT_READFUNCTION, read_data);
		//curl_easy_setopt(lc->c, CURLOPT_READDATA, lc);
		curl_easy_setopt(lc->c, CURLOPT_POSTFIELDS, lc->reqstr);
	}

	lua_getfield(L, 1, "done");
	lua_pushvalue(L, lc_idx); // userdata: must save it until call done
	lua_pushcclosure(L, curl_done, 2);
	lua_set_global_callback(L, "curl_done", lc->c);

	lua_getfield(L, 1, "proxy");
	char *proxy = (char *)lua_tostring(L, -1);
	curl_setproxy(lc, proxy);

	lua_getfield(L, 1, "content_type");
	curl_addheader(lc, "Content-Type", (char *)lua_tostring(L, -1));

	lua_getfield(L, 1, "user_agent");
	curl_addheader(lc, "User-Agent", (char *)lua_tostring(L, -1));

	lua_getfield(L, 1, "authorization");
	curl_addheader(lc, "Authorization", (char *)lua_tostring(L, -1));

	if (lc->headers)
		curl_easy_setopt(lc->c, CURLOPT_HTTPHEADER, lc->headers);

	// return {
	//   cancel = [native function],
	//   stat = [native function],
	// }
	lua_newtable(L);

	lua_pushvalue(L, lc_idx);
	lua_pushcclosure(L, curl_cancel, 1);
	lua_setfield(L, -2, "cancel");

	lua_pushvalue(L, lc_idx);
	lua_pushcclosure(L, curl_stat, 1);
	lua_setfield(L, -2, "stat");

	debug("thread starts");

	uv_work_t *w = (uv_work_t *)zalloc(sizeof(uv_work_t));
	w->data = lc;
	uv_queue_work(loop, w, curl_thread, curl_thread_done);

	return 1;
}
v8::Handle<v8::Value> Find(const v8::Arguments& args) 
{
  v8::HandleScope scope;

  int vid = 0;
  int pid = 0;
  v8::Local<v8::Value> callback;

  if (args.Length() == 0) 
  {
    return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument must be a function"))));
  }

  if (args.Length() == 3) 
  {
    if (args[0]->IsNumber() && args[1]->IsNumber()) 
    {
        vid = (int) args[0]->NumberValue();
        pid = (int) args[1]->NumberValue();
    }

    // callback
    if(!args[2]->IsFunction()) 
    {
        return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("Third argument must be a function"))));
    }

    callback = args[2];
  }

  if (args.Length() == 2) 
  {
    if (args[0]->IsNumber()) 
    {
        vid = (int) args[0]->NumberValue();
    }

    // callback
    if(!args[1]->IsFunction()) 
    {
        return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("Second argument must be a function"))));
    }

    callback = args[1];
  }

  if (args.Length() == 1) 
  {
    // callback
    if(!args[0]->IsFunction()) 
    {
        return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument must be a function"))));
    }

    callback = args[0];
  }

  ListBaton* baton = new ListBaton();
  strcpy(baton->errorString, "");
  baton->callback = v8::Persistent<v8::Value>::New(callback);
  baton->vid = vid;
  baton->pid = pid;

  uv_work_t* req = new uv_work_t();
  req->data = baton;
  uv_queue_work(uv_default_loop(), req, EIO_Find, (uv_after_work_cb)EIO_AfterFind);

  return scope.Close(v8::Undefined());
}