Esempio n. 1
0
void EIO_AfterClose(uv_work_t* req) {
  Nan::HandleScope scope;
  VoidBaton* data = static_cast<VoidBaton*>(req->data);

  v8::Local<v8::Value> argv[1];
  if (data->errorString[0]) {
    argv[0] = v8::Exception::Error(Nan::New<v8::String>(data->errorString).ToLocalChecked());
  } else {
    argv[0] = Nan::Null();

    // We don't have an error, so clean up the write queue for that fd
    _WriteQueue *q = qForFD(data->fd);
    if (q) {
      q->lock();
      QueuedWrite &write_queue = q->get();
      while (!write_queue.empty()) {
        QueuedWrite *del_q = write_queue.next;
        del_q->baton->buffer.Reset();
        del_q->remove();
      }
      q->unlock();
      deleteQForFD(data->fd);
    }
  }
  data->callback.Call(1, argv);

  delete data;
  delete req;
}
Esempio n. 2
0
void EIO_AfterClose(uv_work_t* req) {
  NanScope();

  CloseBaton* data = static_cast<CloseBaton*>(req->data);

  v8::Handle<v8::Value> argv[1];
  if(data->errorString[0]) {
    argv[0] = v8::Exception::Error(NanNew<v8::String>(data->errorString));
  } else {
    argv[0] = NanUndefined();

    // We don't have an error, so clean up the write queue for that fd

    _WriteQueue *q = qForFD(data->fd);
    if (q) {
      q->lock();
      QueuedWrite &write_queue = q->get();
      while (!write_queue.empty()) {
        QueuedWrite *del_q = write_queue.next;
        NanDisposePersistent(del_q->baton->buffer);
        del_q->remove();
      }
      q->unlock();

      deleteQForFD(data->fd);
    }

  }
  data->callback->Call(1, argv);

  delete data->callback;
  delete data;
  delete req;
}
Esempio n. 3
0
void EIO_AfterWrite(uv_work_t* req) {
  NanScope();

  QueuedWrite* queuedWrite = static_cast<QueuedWrite*>(req->data);
  WriteBaton* data = static_cast<WriteBaton*>(queuedWrite->baton);

  v8::Handle<v8::Value> argv[2];
  if(data->errorString[0]) {
    argv[0] = v8::Exception::Error(NanNew<v8::String>(data->errorString));
    argv[1] = NanUndefined();
  } else {
    argv[0] = NanUndefined();
    argv[1] = NanNew<v8::Int32>(data->result);
  }
  data->callback->Call(2, argv);

  if (data->offset < data->bufferLength && !data->errorString[0]) {
    // We're not done with this baton, so throw it right back onto the queue.
	  // Don't re-push the write in the event loop if there was an error; because same error could occur again!
    // TODO: Add a uv_poll here for unix...
    //fprintf(stderr, "Write again...\n");
    uv_queue_work(uv_default_loop(), req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite);
    return;
  }

  int fd = data->fd;
  _WriteQueue *q = qForFD(fd);
  if(!q) {
    NanThrowTypeError("There's no write queue for that file descriptor (after write)!");
    return;
  }

  q->lock();
  QueuedWrite &write_queue = q->get();

  // remove this one from the list
  queuedWrite->remove();

  // If there are any left, start a new thread to write the next one.
  if (!write_queue.empty()) {
    // Always pull the next work item from the head of the queue
    QueuedWrite* nextQueuedWrite = write_queue.next;
    uv_queue_work(uv_default_loop(), &nextQueuedWrite->req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite);
  }
  q->unlock();

  NanDisposePersistent(data->buffer);
  delete data->callback;
  delete data;
  delete queuedWrite;
}
Esempio n. 4
0
void EIO_AfterWrite(uv_work_t* req) {
  Nan::HandleScope scope;

  QueuedWrite* queuedWrite = static_cast<QueuedWrite*>(req->data);
  WriteBaton* data = static_cast<WriteBaton*>(queuedWrite->baton);

  v8::Local<v8::Value> argv[1];
  if (data->errorString[0]) {
    argv[0] = v8::Exception::Error(Nan::New<v8::String>(data->errorString).ToLocalChecked());
  } else {
    argv[0] = Nan::Null();
  }

  if (data->offset < data->bufferLength && !data->errorString[0]) {
    // We're not done with this baton, so throw it right back onto the queue.
    // Don't re-push the write in the event loop if there was an error; because same error could occur again!
    // TODO: Add a uv_poll here for unix...
    uv_queue_work(uv_default_loop(), req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite);
    return;
  }

  // throwing errors instead of returning them at this point is rude
  int fd = data->fd;
  _WriteQueue *q = qForFD(fd);
  if (!q) {
    Nan::ThrowTypeError("There's no write queue for that file descriptor (after write)");
    return;
  }

  q->lock();
  QueuedWrite &write_queue = q->get();

  // remove this one from the list
  queuedWrite->remove();

  data->callback.Call(1, argv);

  // If there are any left, start a new thread to write the next one.
  if (!write_queue.empty()) {
    // Always pull the next work item from the head of the queue
    QueuedWrite* nextQueuedWrite = write_queue.next;
    uv_queue_work(uv_default_loop(), &nextQueuedWrite->req, EIO_Write, (uv_after_work_cb)EIO_AfterWrite);
  }
  q->unlock();

  data->buffer.Reset();
  delete data;
  delete queuedWrite;
}
Esempio n. 5
0
static _WriteQueue *newQForFD(const int fd) {
  _WriteQueue *q = qForFD(fd);

  if (q == NULL) {
    if (write_queues == NULL) {
      write_queues = new _WriteQueue(fd);
      return write_queues;
    } else {
      q = write_queues;
      while (q->_next != NULL) {
        q = q->_next;
      }
      q->_next = new _WriteQueue(fd);
      return q->_next;
    }
  }

  return q;
}