int seaf_wt_monitor_refresh_repo (SeafWTMonitor *monitor, const char *repo_id) { WatchCommand cmd; int res; memset (&cmd, 0, sizeof(cmd)); memcpy (cmd.repo_id, repo_id, 37); cmd.type = CMD_REFRESH_WATCH; int n = pipewriten (monitor->cmd_pipe[1], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] fail to write command pipe.\n"); return -1; } seaf_debug ("send a refresh command, repo %s\n", repo_id); n = pipereadn (monitor->res_pipe[0], &res, sizeof(int)); if (n != sizeof(int)) { seaf_warning ("[wt mon] fail to read result pipe.\n"); return -1; } return res; }
int seaf_wt_monitor_watch_repo (SeafWTMonitor *monitor, const char *repo_id, const char *worktree) { WatchCommand cmd; int res; memset (&cmd, 0, sizeof(cmd)); memcpy (cmd.repo_id, repo_id, 37); cmd.type = CMD_ADD_WATCH; g_strlcpy (cmd.worktree, worktree, SEAF_PATH_MAX); int n = pipewriten (monitor->cmd_pipe[1], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] fail to write command pipe.\n"); return -1; } seaf_debug ("send a watch command, repo %s\n", repo_id); n = pipereadn (monitor->res_pipe[0], &res, sizeof(int)); if (n != sizeof(int)) { seaf_warning ("[wt mon] fail to read result pipe.\n"); return -1; } return res; }
static void job_done_cb (evutil_socket_t fd, short event, void *vdata) { CcnetJob *job = vdata; char buf[1]; if (pipereadn (job->pipefd[0], buf, 1) != 1) { /* g_warning ("[Job Manager] read pipe error: %s\n", strerror(errno)); */ } pipeclose (job->pipefd[0]); pipeclose (job->pipefd[1]); if (job->done_func) { job->done_func (job->result); } ccnet_job_manager_remove_job (job->manager, job->id); }
static void command_read_cb (CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info) { SeafWTMonitorPriv *priv = (SeafWTMonitorPriv *)info; WatchCommand cmd; int n; n = pipereadn (priv->cmd_pipe[0], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] failed to read command.\n"); CFFileDescriptorEnableCallBacks (fdref, kCFFileDescriptorReadCallBack); return; } seaf_debug ("[wt mon] %ld receive command type=%d, repo=%s\n", (long)CFRunLoopGetCurrent(), cmd.type, cmd.repo_id); handle_watch_command (priv, &cmd); CFFileDescriptorEnableCallBacks (fdref, kCFFileDescriptorReadCallBack); }
static void * wt_monitor_job (void *vmonitor) { SeafWTMonitor *monitor = vmonitor; SeafWTMonitorPriv *priv = monitor->priv; /* 2 * sizeof(inotify_event) + 256, should be large enough for one event.*/ WTStatus *status; WatchCommand cmd; int n; int rc; fd_set fds; int inotify_fd; char event_buf[(sizeof(struct inotify_event) << 1) + 256]; gpointer key, value; GHashTableIter iter; FD_SET (priv->cmd_pipe[0], &priv->read_fds); priv->maxfd = priv->cmd_pipe[0]; while (1) { fds = priv->read_fds; rc = select (priv->maxfd + 1, &fds, NULL, NULL, NULL); if (rc < 0 && errno == EINTR) { continue; } else if (rc < 0) { seaf_warning ("[wt mon] select error: %s.\n", strerror(errno)); break; } if (FD_ISSET (priv->cmd_pipe[0], &fds)) { n = pipereadn (priv->cmd_pipe[0], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] failed to read command.\n"); continue; } handle_watch_command (priv, &cmd); } g_hash_table_iter_init (&iter, priv->status_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { inotify_fd = (int)(long)key; if (FD_ISSET (inotify_fd, &fds)) { /* We don't care about the details of the event now. * So we just read out the data but don't parse it. * We may read partial event structure. */ n = read (inotify_fd, event_buf, sizeof(event_buf)); if (n <= 0) { seaf_warning ("[wt mon] failed to read inotify event.\n"); continue; } status = value; if (status) { g_atomic_int_set (&status->last_changed, (gint)time(NULL)); } } } } return NULL; }