/** 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(); }
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; }
Future<Unit> ThreadWheelTimekeeper::after(Duration dur) { auto cob = WTCallback::create(&eventBase_); auto f = cob->getFuture(); eventBase_.runInEventBaseThread([=]{ wheelTimer_->scheduleTimeout(cob, dur); }); return f; }
bool QThreadFutureMap::isAlive(const QString &id) { QFuture<void> *future = getFuture(id); if (future != NULL) { return !future->isFinished(); } return false; }
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()); }); }
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); }); }
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); } } }
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); } }); }
sc_ptrtype const& sc() const { getFuture();return M_sc; }
sc_ptrtype sc() { getFuture();return M_sc; }