Esempio n. 1
0
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;
  }
}
Esempio n. 2
0
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;
    }
  }
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
  };
}
Esempio n. 6
0
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;
}
Esempio n. 7
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();
  }
}
Esempio n. 8
0
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());
    }
  }
}
Esempio n. 9
0
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;
  }
}
Esempio n. 10
0
void DSMonitor::check() {
  if (!N.isNull() && N.getNode()->isCollapsedNode())
    warn();
  unwatch();
}
Esempio n. 11
0
Directory::~Directory() {
  if (watcher_created) {
    emit unwatch(uri);
  }
  interrupt_gio_operation();
}
Esempio n. 12
0
	  void TCP_RECEIVEOBJ::session_reset(void) 
	  {  
			if (watching) unwatch();
	  }
Esempio n. 13
0
	  void TCP_RECEIVEOBJ::session_stop(void) 
	  {  
			if (watching) unwatch();
	  }
Esempio n. 14
0
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;
}
Esempio n. 15
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();

}
Esempio n. 16
0
//------------------------------------------------------------------------------
int Server::shutdown() {
	unwatch(m_socket);
	close(m_socket);
	return 0;
}