예제 #1
0
/** Spawn a thread to read from the pipe connected to the specified fd.
 * Returns a Future that will hold a string with the entire output from
 * that stream. */
Future<w_string> ChildProcess::readPipe(int fd) {
  auto it = pipes_.find(fd);
  if (it == pipes_.end()) {
    return makeFuture(w_string(nullptr));
  }

  auto p = std::make_shared<Promise<w_string>>();
  std::thread thr([this, fd, p] {
    std::string result;
    try {
      auto& pipe = pipes_[fd];
      while (true) {
        char buf[4096];
        auto x = read(pipe->read.fd(), buf, sizeof(buf));
        if (x == 0) {
          // all done
          break;
        }
        if (x == -1) {
          p->setException(std::make_exception_ptr(std::system_error(
              errno, std::generic_category(), "reading from child process")));
          return;
        }
        result.append(buf, x);
      }
      p->setValue(w_string(result.data(), result.size()));
    } catch (const std::exception& exc) {
      p->setException(std::current_exception());
    }
  });

  thr.detach();
  return p->getFuture();
}
예제 #2
0
Future<Unit> ThreadWheelTimekeeper::after(Duration dur) {
  auto cob = WTCallback::create(&eventBase_);
  auto f = cob->getFuture();
  //
  // Even shared_ptr of cob is captured in lambda this is still somewhat *racy*
  // because it will be released once timeout is scheduled. So technically there
  // is no gurantee that EventBase thread can safely call timeout callback.
  // However due to fact that we are having circular reference here:
  // WTCallback->Promise->Core->WTCallbak, so three of them won't go away until
  // we break the circular reference. The break happens either in
  // WTCallback::timeoutExpired or WTCallback::interruptHandler. Former means
  // timeout callback is being safely executed. Latter captures shared_ptr of
  // WTCallback again in another lambda for canceling timeout. The moment
  // canceling timeout is executed in EventBase thread, the actual timeout
  // callback has either been executed, or will never be executed. So we are
  // fine here.
  //
  if (!eventBase_.runInEventBaseThread([this, cob, dur]{
        wheelTimer_->scheduleTimeout(cob.get(), dur);
      })) {
    // Release promise to break the circular reference. Because if
    // scheduleTimeout fails, there is nothing to *promise*. Internally
    // Core would automatically set an exception result when Promise is
    // destructed before fulfilling.
    // This is either called from EventBase thread, or here.
    // They are somewhat racy but given the rare chance this could fail,
    // I don't see it is introducing any problem yet.
    auto promise = cob->stealPromise();
    if (!promise.isFulfilled()) {
      promise.setException(NoTimekeeper{});
    }
  }
  return f;
}
예제 #3
0
Future<Unit> ThreadWheelTimekeeper::after(Duration dur) {
  auto cob = WTCallback::create(&eventBase_);
  auto f = cob->getFuture();
  eventBase_.runInEventBaseThread([=]{
    wheelTimer_->scheduleTimeout(cob, dur);
  });
  return f;
}
예제 #4
0
bool QThreadFutureMap::isAlive(const QString &id)
{
  QFuture<void> *future = getFuture(id);
  if (future != NULL) {
    return !future->isFinished();
  }

  return false;
}
예제 #5
0
folly::Future<std::unique_ptr<Tree>> LocalStore::getTree(const Hash& id) const {
  return getFuture(KeySpace::TreeFamily, id.getBytes())
      .thenValue([id](StoreResult&& data) {
        if (!data.isValid()) {
          return std::unique_ptr<Tree>(nullptr);
        }
        return deserializeGitTree(id, data.bytes());
      });
}
예제 #6
0
folly::Future<std::unique_ptr<Blob>> LocalStore::getBlob(const Hash& id) const {
  return getFuture(KeySpace::BlobFamily, id.getBytes())
      .thenValue([id](StoreResult&& data) {
        if (!data.isValid()) {
          return std::unique_ptr<Blob>(nullptr);
        }
        auto buf = data.extractIOBuf();
        return deserializeGitBlob(id, &buf);
      });
}
예제 #7
0
void QThreadFutureMap::removeDeadThread()
{
  QList<QString> keyList = this->keys();
  foreach (const QString &key, keyList) {
    QFuture<void> *future = getFuture(key);
    if (future != NULL) {
      if (future->isFinished()) {
        remove(key);
      }
    }
  }
예제 #8
0
folly::Future<optional<BlobMetadata>> LocalStore::getBlobMetadata(
    const Hash& id) const {
  return getFuture(KeySpace::BlobMetaDataFamily, id.getBytes())
      .thenValue([id](StoreResult&& data) -> optional<BlobMetadata> {
        if (!data.isValid()) {
          return std::nullopt;
        } else {
          return SerializedBlobMetadata::parse(id, data);
        }
      });
}
예제 #9
0
 sc_ptrtype const& sc() const { getFuture();return M_sc; }
예제 #10
0
 sc_ptrtype sc() { getFuture();return M_sc; }