static void dna_helper_close_pipes() { if (dna_helper_stdin != -1) { if (config.debug.dnahelper) DEBUGF("DNAHELPER closing stdin pipe fd=%d", dna_helper_stdin); close(dna_helper_stdin); dna_helper_stdin = -1; } if (sched_requests.poll.fd != -1) { unwatch(&sched_requests); sched_requests.poll.fd = -1; } if (dna_helper_stdout != -1) { if (config.debug.dnahelper) DEBUGF("DNAHELPER closing stdout pipe fd=%d", dna_helper_stdout); close(dna_helper_stdout); dna_helper_stdout = -1; } if (sched_replies.poll.fd != -1) { unwatch(&sched_replies); sched_replies.poll.fd = -1; } if (dna_helper_stderr != -1) { if (config.debug.dnahelper) DEBUGF("DNAHELPER closing stderr pipe fd=%d", dna_helper_stderr); close(dna_helper_stderr); dna_helper_stderr = -1; } if (sched_errors.poll.fd != -1) { unwatch(&sched_errors); sched_errors.poll.fd = -1; } }
static void monitor_requests(struct sched_ent *alarm) { if (config.debug.dnahelper) { DEBUGF("sched_requests.poll.fd=%d .revents=%s", sched_requests.poll.fd, strbuf_str(strbuf_append_poll_events(strbuf_alloca(40), sched_requests.poll.revents)) ); } assert(alarm == &sched_requests); // On Linux, poll(2) returns ERR when the remote reader dies. On Mac OS X, poll(2) returns NVAL, // which is documented to mean the file descriptor is not open, but testing revealed that in this // case it is still open. See issue #5. if (sched_requests.poll.revents & (POLLHUP | POLLERR | POLLNVAL)) { if (config.debug.dnahelper) DEBUGF("DNAHELPER closing stdin fd=%d", dna_helper_stdin); close(dna_helper_stdin); dna_helper_stdin = -1; unwatch(&sched_requests); sched_requests.poll.fd = -1; dna_helper_kill(); } else if (sched_requests.poll.revents & POLLOUT) { if (request_bufptr) { if (request_bufptr < request_bufend) { size_t remaining = request_bufend - request_bufptr; sigPipeFlag = 0; ssize_t written = write_nonblock(dna_helper_stdin, request_bufptr, remaining); if (sigPipeFlag) { /* Broken pipe is probably due to a dead helper, but make sure the helper is dead, just to be sure. It will be harvested at the next harvester() timeout, and restarted on the first request that arrives after a suitable pause has elapsed. Losing the current request is not a big problem, because DNA preemptively retries. */ INFO("DNAHELPER got SIGPIPE on write -- stopping process"); dna_helper_kill(); } else if (written > 0) { if (config.debug.dnahelper) DEBUGF("DNAHELPER wrote request %s", alloca_toprint(-1, request_bufptr, written)); request_bufptr += written; } } if (request_bufptr >= request_bufend) { // Request sent successfully. Start watching for reply. request_bufptr = request_bufend = NULL; awaiting_reply = 1; sched_timeout.alarm = gettime_ms() + 1500; sched_timeout.deadline = sched_timeout.alarm + 3000; schedule(&sched_timeout); } } // If no request to send, stop monitoring the helper's stdin pipe. if (!request_bufptr) { unwatch(&sched_requests); sched_requests.poll.fd = -1; } } }
Directory::Directory(Core *c, QString p_uri) : Core_ally(c), uri(p_uri) { connect(this, SIGNAL(watch(QString)), core->get_directory_watcher(), SLOT(add(QString))); connect(this, SIGNAL(unwatch(QString)), core->get_directory_watcher(), SLOT(remove(QString))); connect(core->get_directory_watcher(), SIGNAL(directory_changed(QString)), this, SLOT(directory_changed(QString))); async_result_type = async_result_unexpected; gcancellable = 0; need_update = false; watcher_created = false; uri = canonize(uri); Special_uri special_uri(uri); if (special_uri.name() == Special_uri::places) { connect(core->get_mount_manager(), SIGNAL(mounts_changed(QList<Gio_mount>)), this, SLOT(refresh())); connect(core->get_bookmarks(), SIGNAL(changed()), this, SLOT(refresh())); connect(core->get_user_dirs(), SIGNAL(changed()), this, SLOT(refresh())); } QTimer* t = new QTimer(this); connect(t, SIGNAL(timeout()), this, SLOT(refresh_timeout())); t->start(watcher_refresh_timeout); refresh_timer.restart(); }
bool EventManager::close(int fd, bool force_close) { auto ret = true; if (_fds.find(fd) != _fds.end() && _fds[fd].find(EventType::CLOSE) != _fds[fd].end()) { auto f = _fds[fd][EventType::CLOSE]; if ((ret &= unwatch(fd)) || force_close) _add_close_fd(fd); f(fd);//TODO make it possible to transfer state and buffer when close return ret; } if ((ret &= unwatch(fd)) || force_close) _add_close_fd(fd); return true; }
static void unregister_roots() { watch_root* root; while ((root = array_pop(roots)) != NULL) { userlog(LOG_INFO, "unregistering root: %s", root->name); unwatch(root->id); free(root->name); free(root); }; }
static int rhizome_server_free_http_request(rhizome_http_request *r) { unwatch(&r->alarm); unschedule(&r->alarm); close(r->alarm.poll.fd); if (r->buffer) free(r->buffer); if (r->blob) sqlite3_blob_close(r->blob); free(r); return 0; }
static void monitor_replies(struct sched_ent *alarm) { if (config.debug.dnahelper) { DEBUGF("sched_replies.poll.fd=%d .revents=%s", sched_replies.poll.fd, strbuf_str(strbuf_append_poll_events(strbuf_alloca(40), sched_replies.poll.revents)) ); } assert(alarm == &sched_replies); if (sched_replies.poll.revents & POLLIN) { size_t remaining = reply_buffer + sizeof reply_buffer - reply_bufend; ssize_t nread = read_nonblock(sched_replies.poll.fd, reply_bufend, remaining); if (nread > 0) { char *bufp = reply_buffer; char *readp = reply_bufend; reply_bufend += nread; char *nl; while (nread > 0 && (nl = srv_strnstr(readp, nread, "\n"))) { size_t len = nl - bufp + 1; if (discarding_until_nl) { if (config.debug.dnahelper) DEBUGF("Discarding %s", alloca_toprint(-1, bufp, len)); discarding_until_nl = 0; } else { handle_reply_line(bufp, len); } readp = bufp = nl + 1; nread = reply_bufend - readp; } if (bufp != reply_buffer) { size_t len = reply_bufend - bufp; memmove(reply_buffer, bufp, len); reply_bufend = reply_buffer + len; } else if (reply_bufend >= reply_buffer + sizeof reply_buffer) { WHY("DNAHELPER reply buffer overrun"); if (config.debug.dnahelper) DEBUGF("Discarding %s", alloca_toprint(-1, reply_buffer, sizeof reply_buffer)); reply_bufend = reply_buffer; discarding_until_nl = 1; } } } if (sched_replies.poll.revents & (POLLHUP | POLLERR | POLLNVAL)) { if (config.debug.dnahelper) DEBUGF("DNAHELPER closing stdout fd=%d", dna_helper_stdout); close(dna_helper_stdout); dna_helper_stdout = -1; unwatch(&sched_replies); sched_replies.poll.fd = -1; dna_helper_kill(); } }
void DSMonitor::watch(DSNodeHandle N, std::vector<Value*> VS, std::string M) { if (N.isNull() || N.getNode()->isCollapsedNode()) { unwatch(); return; } this->N = N; this->VS = VS; this->message = M; DSGraph *G = N.getNode()->getParentGraph(); caption = getCaption(N.getNode(), G); if (!VS.empty()) { Instruction *I = getInstruction(VS[0]); if (I && I->getMetadata("dbg")) { const DebugLoc DL = I->getDebugLoc(); auto *scope = cast<DIScope>(DL.getScope()); location = scope->getFilename().str() + ":" + std::to_string(DL.getLine()) + ":" + std::to_string(DL.getCol()); } } }
static void monitor_errors(struct sched_ent *alarm) { if (debug & DEBUG_DNAHELPER) { DEBUGF("sched_errors.poll.fd=%d .revents=%s", sched_errors.poll.fd, strbuf_str(strbuf_append_poll_events(strbuf_alloca(40), sched_errors.poll.revents)) ); } if (sched_errors.poll.revents & POLLIN) { char buffer[1024]; ssize_t nread = read_nonblock(sched_errors.poll.fd, buffer, sizeof buffer); if (nread > 0) WHYF("DNAHELPER stderr %s", alloca_toprint(-1, buffer, nread)); } if (sched_errors.poll.revents & (POLLHUP | POLLERR | POLLNVAL)) { if (debug & DEBUG_DNAHELPER) DEBUGF("DNAHELPER closing stderr fd=%d", dna_helper_stderr); close(dna_helper_stderr); dna_helper_stderr = -1; unwatch(&sched_errors); sched_errors.poll.fd = -1; } }
void DSMonitor::check() { if (!N.isNull() && N.getNode()->isCollapsedNode()) warn(); unwatch(); }
Directory::~Directory() { if (watcher_created) { emit unwatch(uri); } interrupt_gio_operation(); }
void TCP_RECEIVEOBJ::session_reset(void) { if (watching) unwatch(); }
void TCP_RECEIVEOBJ::session_stop(void) { if (watching) unwatch(); }
int monitor() { // Buffer for File Descriptor char buffer[EVENT_BUF_LEN]; // inotify_event of the event struct inotify_event *event = NULL; // The path of touched directory or file char *path = NULL; int len; // Wait for events while (len = read(fd, buffer, EVENT_BUF_LEN)) { if (len < 0) { printf("Read() error"); return -1; } // index of the event into file descriptor int i = 0; while (i < len) { // inotify_event of the event event = (struct inotify_event*) &buffer[i]; // Build the full path of the directory or symbolic link LIST_NODE *node = get_from_wd(event->wd); if (node != NULL) { WD_DATA *wd_data = (WD_DATA *) node->data; path = malloc(sizeof(char) * (strlen(wd_data->path) + strlen(event->name) + 2)); strcpy(path, wd_data->path); strcat(path, event->name); strcat(path, "/"); } else continue; // IN_CREATE Event if (event->mask & IN_CREATE) { // Check if it is a folder. If yes watch it if (event->mask & IN_ISDIR) watch(path, 0); else { // check if it is a link. if yes watch it. DIR *dir_stream = opendir(path); if (dir_stream != NULL) { // resolve symbolic link char *realpath = resolve_real_path(path); watch(realpath, 1); } closedir(dir_stream); } } // IN_DELETE event else if (event->mask & IN_DELETE) { // Starts build the full path of the // Check if it is a folder. If yes unwatch it if (event->mask & IN_ISDIR) unwatch(path); else { // Resolve the real path of the symbolic link char* resolved = resolve_real_path(path); printf("PATH TO DELETE: %s\n", resolved); } } // Next event i += EVENT_SIZE + event->len; } } return 0; }
void EventManager::handle_events(int ret, const struct epoll_event* events) { if (ret == -1) { if (errno != EINTR) { //error handle L.error_exit("epoll_wait"); } return; } for (int i = 0; i < ret; i++) { _current_fd = events[i].data.fd; auto has_callback = _fds.find(_current_fd) != _fds.end(); if (!has_callback) { //可能是某个回调unwatch或者close了该fd cout << Utils::RED("waited fd has no callback " + to_string(_current_fd) + " pid = " + to_string(Utils::getpid())) << endl; continue; } auto flags = events[i].events; _current_cb = _fds[_current_fd]; if (_current_cb.find(EventType::CONNECT) != _current_cb.end()) { auto f/*copy to avoid erase when calling*/ = _current_cb[EventType::CONNECT]; if (flags & (EPOLLERR|EPOLLHUP)) { goto CONNECT_NG; } if (flags & EPOLLOUT) { int result; socklen_t result_len = sizeof(result); if (getsockopt(_current_fd, SOL_SOCKET, SO_ERROR, &result, &result_len) < 0) { goto CONNECT_NG; } if (result != 0) { goto CONNECT_NG; } else { goto CONNECT_OK; } } CONNECT_NG: /*******实现要求******* ********************** **** 1.只回调一次 **** ***** 2.fd占住(所以不能close) ******** *********************** **/ _fds[_current_fd].erase(EventType::CONNECT); _current_cb.erase(EventType::CONNECT); unwatch(_current_fd); f(_current_fd, ConnectResult::NG); continue; CONNECT_OK: //回调前就删除 _fds[_current_fd].erase(EventType::CONNECT); _current_cb.erase(EventType::CONNECT); f(_current_fd, ConnectResult::OK); } if (flags & EPOLLIN) { if (_current_cb.find(EventType::READ) != _current_cb.end()) { auto f/*copy to avoid erase when calling*/ = _current_cb[EventType::READ]; if (f.want_message()) { f(_current_fd, Protocol::read(_current_fd)); } else { f(_current_fd); } } else { L.error_log("fd " + to_string(_current_fd) + " has no read handler"); //error handle } } if (flags & EPOLLOUT) { if (_current_cb.find(EventType::WRITE) != _current_cb.end()) { auto f = _current_cb[EventType::WRITE]; f(_current_fd); } } if (flags & EPOLLERR) { if (_current_cb.find(EventType::ERROR) != _current_cb.end()) { auto f = _current_cb[EventType::ERROR]; f(_current_fd); } else { cout << Utils::RED("EPOLLERR no handler") << endl; } } if (flags & (EPOLLRDHUP | EPOLLHUP)) { if (_current_cb.find(EventType::CLOSE) != _current_cb.end()) { auto f/*copy to avoid erase when calling*/ = _current_cb[EventType::CLOSE]; if (unwatch(_current_fd)) _add_close_fd(_current_fd); f(_current_fd);//TODO make it possible to transfer state and buffer when close } else { //no close handler registered, try to unwatch + close if (unwatch(_current_fd)) _add_close_fd(_current_fd); else { L.error_log("failed when try to unwatch closed fd " + to_string(_current_fd)); } } } } _current_fd = -1; for (auto fd : _close_fds) { ::close(fd); } _close_fds.clear(); }
//------------------------------------------------------------------------------ int Server::shutdown() { unwatch(m_socket); close(m_socket); return 0; }