<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[23009] trunk/launchd/src</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.macosforge.org/projects/launchd/changeset/23009">23009</a></dd>
<dt>Author</dt> <dd>zarzycki@apple.com</dd>
<dt>Date</dt> <dd>2007-01-11 16:33:20 -0800 (Thu, 11 Jan 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>&lt;rdar://problem/4911067&gt; KeepAlive with PathState should monitor for file creation state change</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunklaunchdsrclaunchdc">trunk/launchd/src/launchd.c</a></li>
<li><a href="#trunklaunchdsrclaunchd_core_logicc">trunk/launchd/src/launchd_core_logic.c</a></li>
<li><a href="#trunklaunchdsrclaunchd_core_logich">trunk/launchd/src/launchd_core_logic.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunklaunchdsrclaunchdc"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/launchd.c (23008 => 23009)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/launchd.c        2007-01-10 21:58:22 UTC (rev 23008)
+++ trunk/launchd/src/launchd.c        2007-01-12 00:33:20 UTC (rev 23009)
</span><span class="lines">@@ -645,7 +645,7 @@
</span><span class="cx"> 
</span><span class="cx">         if (new_networking_state != network_up) {
</span><span class="cx">                 network_up = new_networking_state;
</span><del>-                jobmgr_dispatch_all_other_semaphores(root_jobmgr, NULL);
</del><ins>+                jobmgr_dispatch_all_semaphores(root_jobmgr);
</ins><span class="cx">         }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunklaunchdsrclaunchd_core_logicc"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/launchd_core_logic.c (23008 => 23009)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/launchd_core_logic.c        2007-01-10 21:58:22 UTC (rev 23008)
+++ trunk/launchd/src/launchd_core_logic.c        2007-01-12 00:33:20 UTC (rev 23009)
</span><span class="lines">@@ -104,8 +104,10 @@
</span><span class="cx"> static void machservice_setup_options(launch_data_t obj, const char *key, void *context);
</span><span class="cx"> static void machservice_resetport(job_t j, struct machservice *ms);
</span><span class="cx"> static struct machservice *machservice_new(job_t j, const char *name, mach_port_t *serviceport);
</span><ins>+static void machservice_ignore(job_t j, struct machservice *ms);
+static void machservice_watch(job_t j, struct machservice *ms);
</ins><span class="cx"> static void machservice_delete(struct machservice *);
</span><del>-static void machservice_watch(struct machservice *);
</del><ins>+static void machservice_request_notifications(struct machservice *);
</ins><span class="cx"> static mach_port_t machservice_port(struct machservice *);
</span><span class="cx"> static job_t machservice_job(struct machservice *);
</span><span class="cx"> static bool machservice_hidden(struct machservice *);
</span><span class="lines">@@ -127,19 +129,6 @@
</span><span class="cx"> static void socketgroup_callback(job_t j, struct kevent *kev);
</span><span class="cx"> static void socketgroup_setup(launch_data_t obj, const char *key, void *context);
</span><span class="cx"> 
</span><del>-struct watchpath {
-        SLIST_ENTRY(watchpath) sle;
-        int fd;
-        unsigned int is_qdir:1, __junk:31;
-        char name[0];
-};
-
-static bool watchpath_new(job_t j, const char *name, bool qdir);
-static void watchpath_delete(job_t j, struct watchpath *wp);
-static void watchpath_watch(job_t j, struct watchpath *wp);
-static void watchpath_ignore(job_t j, struct watchpath *wp);
-static void watchpath_callback(job_t j, struct kevent *kev);
-
</del><span class="cx"> struct calendarinterval {
</span><span class="cx">         SLIST_ENTRY(calendarinterval) sle;
</span><span class="cx">         struct tm when;
</span><span class="lines">@@ -178,12 +167,15 @@
</span><span class="cx">         FAILED_EXIT,
</span><span class="cx">         PATH_EXISTS,
</span><span class="cx">         PATH_MISSING,
</span><ins>+        PATH_CHANGES,
+        DIR_NOT_EMPTY,
</ins><span class="cx">         // FILESYSTEMTYPE_IS_MOUNTED,        /* for nfsiod, but maybe others */
</span><span class="cx"> } semaphore_reason_t;
</span><span class="cx"> 
</span><span class="cx"> struct semaphoreitem {
</span><span class="cx">         SLIST_ENTRY(semaphoreitem) sle;
</span><span class="cx">         semaphore_reason_t why;
</span><ins>+        int fd;
</ins><span class="cx">         char what[0];
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -191,6 +183,9 @@
</span><span class="cx"> static void semaphoreitem_delete(job_t j, struct semaphoreitem *si);
</span><span class="cx"> static void semaphoreitem_setup(launch_data_t obj, const char *key, void *context);
</span><span class="cx"> static void semaphoreitem_setup_paths(launch_data_t obj, const char *key, void *context);
</span><ins>+static void semaphoreitem_callback(job_t j, struct kevent *kev);
+static void semaphoreitem_watch(job_t j, struct semaphoreitem *si);
+static void semaphoreitem_ignore(job_t j, struct semaphoreitem *si);
</ins><span class="cx"> 
</span><span class="cx"> struct jobmgr_s {
</span><span class="cx">         SLIST_ENTRY(jobmgr_s) sle;
</span><span class="lines">@@ -231,7 +226,6 @@
</span><span class="cx">         kq_callback kqjob_callback;
</span><span class="cx">         SLIST_ENTRY(job_s) sle;
</span><span class="cx">         SLIST_HEAD(, socketgroup) sockets;
</span><del>-        SLIST_HEAD(, watchpath) vnodes;
</del><span class="cx">         SLIST_HEAD(, calendarinterval) cal_intervals;
</span><span class="cx">         SLIST_HEAD(, envitem) global_env;
</span><span class="cx">         SLIST_HEAD(, envitem) env;
</span><span class="lines">@@ -356,9 +350,9 @@
</span><span class="cx"> void
</span><span class="cx"> job_ignore(job_t j)
</span><span class="cx"> {
</span><ins>+        struct semaphoreitem *si;
</ins><span class="cx">         struct socketgroup *sg;
</span><span class="cx">         struct machservice *ms;
</span><del>-        struct watchpath *wp;
</del><span class="cx"> 
</span><span class="cx">         if (j-&gt;currently_ignored) {
</span><span class="cx">                 return;
</span><span class="lines">@@ -370,12 +364,12 @@
</span><span class="cx">                 socketgroup_ignore(j, sg);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        SLIST_FOREACH(wp, &amp;j-&gt;vnodes, sle) {
-                watchpath_ignore(j, wp);
</del><ins>+        SLIST_FOREACH(ms, &amp;j-&gt;machservices, sle) {
+                machservice_ignore(j, ms);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        SLIST_FOREACH(ms, &amp;j-&gt;machservices, sle) {
-                job_assumes(j, runtime_remove_mport(ms-&gt;port) == KERN_SUCCESS);
</del><ins>+        SLIST_FOREACH(si, &amp;j-&gt;semaphores, sle) {
+                semaphoreitem_ignore(j, si);
</ins><span class="cx">         }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -385,7 +379,6 @@
</span><span class="cx">         struct semaphoreitem *si;
</span><span class="cx">         struct socketgroup *sg;
</span><span class="cx">         struct machservice *ms;
</span><del>-        struct watchpath *wp;
</del><span class="cx"> 
</span><span class="cx">         if (!j-&gt;currently_ignored) {
</span><span class="cx">                 return;
</span><span class="lines">@@ -397,19 +390,12 @@
</span><span class="cx">                 socketgroup_watch(j, sg);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        SLIST_FOREACH(wp, &amp;j-&gt;vnodes, sle) {
-                watchpath_watch(j, wp);
-        }
-
</del><span class="cx">         SLIST_FOREACH(ms, &amp;j-&gt;machservices, sle) {
</span><del>-                job_assumes(j, runtime_add_mport(ms-&gt;port, NULL, 0) == KERN_SUCCESS);
</del><ins>+                machservice_watch(j, ms);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         SLIST_FOREACH(si, &amp;j-&gt;semaphores, sle) {
</span><del>-                if (si-&gt;why == PATH_EXISTS || si-&gt;why == PATH_MISSING) {
-                        /* Maybe another job has the inverse path based semaphore as this job */
-                        jobmgr_dispatch_all_other_semaphores(root_jobmgr, j);
-                }
</del><ins>+                semaphoreitem_watch(j, si);
</ins><span class="cx">         }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -583,7 +569,6 @@
</span><span class="cx"> {
</span><span class="cx">         struct calendarinterval *ci;
</span><span class="cx">         struct socketgroup *sg;
</span><del>-        struct watchpath *wp;
</del><span class="cx">         struct limititem *li;
</span><span class="cx">         struct envitem *ei;
</span><span class="cx">         struct machservice *ms;
</span><span class="lines">@@ -627,9 +612,6 @@
</span><span class="cx">         while ((sg = SLIST_FIRST(&amp;j-&gt;sockets))) {
</span><span class="cx">                 socketgroup_delete(j, sg);
</span><span class="cx">         }
</span><del>-        while ((wp = SLIST_FIRST(&amp;j-&gt;vnodes))) {
-                watchpath_delete(j, wp);
-        }
</del><span class="cx">         while ((ci = SLIST_FIRST(&amp;j-&gt;cal_intervals))) {
</span><span class="cx">                 calendarinterval_delete(j, ci);
</span><span class="cx">         }
</span><span class="lines">@@ -1299,9 +1281,6 @@
</span><span class="cx"> void
</span><span class="cx"> job_import_array(job_t j, const char *key, launch_data_t value)
</span><span class="cx"> {
</span><del>-        bool is_q_dir = false;
-        bool is_wp = false;
-
</del><span class="cx">         switch (key[0]) {
</span><span class="cx">         case 'l':
</span><span class="cx">         case 'L':
</span><span class="lines">@@ -1314,14 +1293,24 @@
</span><span class="cx">         case 'q':
</span><span class="cx">         case 'Q':
</span><span class="cx">                 if (strcasecmp(key, LAUNCH_JOBKEY_QUEUEDIRECTORIES) == 0) {
</span><del>-                        is_q_dir = true;
-                        is_wp = true;
</del><ins>+                        size_t i, qd_cnt = launch_data_array_get_count(value);
+                        const char *thepath;
+                        for (i = 0; i &lt; qd_cnt; i++) {
+                                thepath = launch_data_get_string(launch_data_array_get_index(value, i));
+                                semaphoreitem_new(j, DIR_NOT_EMPTY, thepath);
+                        }
+
</ins><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">         case 'w':
</span><span class="cx">         case 'W':
</span><span class="cx">                 if (strcasecmp(key, LAUNCH_JOBKEY_WATCHPATHS) == 0) {
</span><del>-                        is_wp = true;
</del><ins>+                        size_t i, wp_cnt = launch_data_array_get_count(value);
+                        const char *thepath;
+                        for (i = 0; i &lt; wp_cnt; i++) {
+                                thepath = launch_data_get_string(launch_data_array_get_index(value, i));
+                                semaphoreitem_new(j, PATH_CHANGES, thepath);
+                        }
</ins><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">         case 'b':
</span><span class="lines">@@ -1341,15 +1330,6 @@
</span><span class="cx">         default:
</span><span class="cx">                 break;
</span><span class="cx">         }
</span><del>-
-        if (is_wp) {
-                size_t i, wp_cnt = launch_data_array_get_count(value);
-                const char *thepath;
-                for (i = 0; i &lt; wp_cnt; i++) {
-                        thepath = launch_data_get_string(launch_data_array_get_index(value, i));
-                        watchpath_new(j, thepath, is_q_dir);
-                }
-        }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><span class="lines">@@ -1752,7 +1732,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 break;
</span><span class="cx">         case EVFILT_VNODE:
</span><del>-                watchpath_callback(j, kev);
</del><ins>+                semaphoreitem_callback(j, kev);
</ins><span class="cx">                 break;
</span><span class="cx">         case EVFILT_READ:
</span><span class="cx">                 if (kev-&gt;ident == (uintptr_t)j-&gt;log_redirect_fd) {
</span><span class="lines">@@ -2365,111 +2345,82 @@
</span><span class="cx">         }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool
-watchpath_new(job_t j, const char *name, bool qdir)
-{
-        struct watchpath *wp = calloc(1, sizeof(struct watchpath) + strlen(name) + 1);
-
-        if (!job_assumes(j, wp != NULL)) {
-                return false;
-        }
-
-        wp-&gt;is_qdir = qdir;
-
-        wp-&gt;fd = -1; /* watchpath_watch() will open this */
-
-        strcpy(wp-&gt;name, name);
-
-        SLIST_INSERT_HEAD(&amp;j-&gt;vnodes, wp, sle);
-
-        return true;
-}       
-
-void
-watchpath_delete(job_t j, struct watchpath *wp) 
-{
-        if (wp-&gt;fd != -1) {
-                job_assumes(j, close(wp-&gt;fd) != -1);
-        }
-
-        SLIST_REMOVE(&amp;j-&gt;vnodes, wp, watchpath, sle);
-
-        free(wp);
-}       
-
</del><span class="cx"> void    
</span><del>-watchpath_ignore(job_t j, struct watchpath *wp)
</del><ins>+semaphoreitem_ignore(job_t j, struct semaphoreitem *si)
</ins><span class="cx"> {       
</span><del>-        if (wp-&gt;fd != -1) {
-                job_log(j, LOG_DEBUG, &quot;Ignoring Vnode: %d&quot;, wp-&gt;fd);
-                job_assumes(j, kevent_mod(wp-&gt;fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1);
</del><ins>+        if (si-&gt;fd != -1) {
+                job_log(j, LOG_DEBUG, &quot;Ignoring Vnode: %d&quot;, si-&gt;fd);
+                job_assumes(j, kevent_mod(si-&gt;fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1);
</ins><span class="cx">         }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><del>-watchpath_watch(job_t j, struct watchpath *wp)
</del><ins>+semaphoreitem_watch(job_t j, struct semaphoreitem *si)
</ins><span class="cx"> {
</span><del>-        int fflags = NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK;
-        int qdir_file_cnt;
-
-        if (!wp-&gt;is_qdir) {
-                fflags |= NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE;
</del><ins>+        char parentdir_path[PATH_MAX], *which_path = si-&gt;what;
+        int fflags = 0;
+        
+        switch (si-&gt;why) {
+        case PATH_EXISTS:
+                fflags = NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_EXTEND|NOTE_WRITE;
+                strlcpy(parentdir_path, dirname(si-&gt;what), sizeof(parentdir_path));
+                which_path = parentdir_path;
+                break;
+        case PATH_MISSING:
+                fflags = NOTE_DELETE|NOTE_RENAME;
+                break;
+        case PATH_CHANGES:
+                fflags = NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_EXTEND|NOTE_WRITE|NOTE_ATTRIB|NOTE_LINK;
+                break;
+        default:
+                return;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (wp-&gt;fd == -1) {
-                wp-&gt;fd = _fd(open(wp-&gt;name, O_EVTONLY|O_NOCTTY|O_NOFOLLOW));
</del><ins>+        if (si-&gt;fd == -1) {
+                si-&gt;fd = _fd(open(which_path, O_EVTONLY|O_NOCTTY));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (wp-&gt;fd == -1) {
-                return job_log_error(j, LOG_ERR, &quot;Watchpath monitoring failed on \&quot;%s\&quot;&quot;, wp-&gt;name);
</del><ins>+        if (si-&gt;fd == -1) {
+                return job_log_error(j, LOG_ERR, &quot;Watchpath monitoring failed on \&quot;%s\&quot;&quot;, which_path);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        job_log(j, LOG_DEBUG, &quot;Watching Vnode: %d&quot;, wp-&gt;fd);
-        job_assumes(j, kevent_mod(wp-&gt;fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, fflags, 0, j) != -1);
-
-        if (!wp-&gt;is_qdir) {
-                return;
-        }
-
-        if (-1 == (qdir_file_cnt = dir_has_files(j, wp-&gt;name))) {
-                job_log_error(j, LOG_ERR, &quot;dir_has_files(\&quot;%s\&quot;, ...)&quot;, wp-&gt;name);
-        } else if (qdir_file_cnt &gt; 0) {
-                job_dispatch(j, true);
-        }
</del><ins>+        job_log(j, LOG_DEBUG, &quot;Watching Vnode: %d&quot;, si-&gt;fd);
+        job_assumes(j, kevent_mod(si-&gt;fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, fflags, 0, j) != -1);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><del>-watchpath_callback(job_t j, struct kevent *kev)
</del><ins>+semaphoreitem_callback(job_t j, struct kevent *kev)
</ins><span class="cx"> {
</span><del>-        struct watchpath *wp;
-        int dir_file_cnt;
</del><ins>+        struct semaphoreitem *si;
</ins><span class="cx"> 
</span><del>-        SLIST_FOREACH(wp, &amp;j-&gt;vnodes, sle) {
-                if (wp-&gt;fd == (int)kev-&gt;ident) {
</del><ins>+        SLIST_FOREACH(si, &amp;j-&gt;semaphores, sle) {
+                switch (si-&gt;why) {
+                case PATH_CHANGES:
+                case PATH_EXISTS:
+                case PATH_MISSING:
</ins><span class="cx">                         break;
</span><ins>+                default:
+                        continue;
</ins><span class="cx">                 }
</span><ins>+
+                if (si-&gt;fd == (int)kev-&gt;ident) {
+                        break;
+                }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        job_assumes(j, wp != NULL);
</del><ins>+        if (!job_assumes(j, si != NULL)) {
+                return;
+        }
</ins><span class="cx"> 
</span><span class="cx">         if ((NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE) &amp; kev-&gt;fflags) {
</span><del>-                job_log(j, LOG_DEBUG, &quot;Path invalidated: %s&quot;, wp-&gt;name);
-                job_assumes(j, close(wp-&gt;fd) == 0);
-                wp-&gt;fd = -1; /* this will get fixed in watchpath_watch() */
-        } else if (!wp-&gt;is_qdir) {
-                job_log(j, LOG_DEBUG, &quot;Watch path modified: %s&quot;, wp-&gt;name);
-        } else {
-                job_log(j, LOG_DEBUG, &quot;Queue directory modified: %s&quot;, wp-&gt;name);
-
-                if (-1 == (dir_file_cnt = dir_has_files(j, wp-&gt;name))) {
-                        job_log_error(j, LOG_ERR, &quot;dir_has_files(\&quot;%s\&quot;, ...)&quot;, wp-&gt;name);
-                } else if (0 == dir_file_cnt) {
-                        job_log(j, LOG_DEBUG, &quot;Spurious wake up, directory is empty again: %s&quot;, wp-&gt;name);
-                        return;
-                }
</del><ins>+                job_log(j, LOG_DEBUG, &quot;Path invalidated: %s&quot;, si-&gt;what);
+                job_assumes(j, close(si-&gt;fd) == 0);
+                si-&gt;fd = -1; /* this will get fixed in semaphoreitem_watch() */
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        job_dispatch(j, true);
</del><ins>+        job_log(j, LOG_DEBUG, &quot;Watch path modified: %s&quot;, si-&gt;what);
+
+        job_dispatch(j, si-&gt;why == PATH_CHANGES ? true : false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool
</span><span class="lines">@@ -2818,6 +2769,8 @@
</span><span class="cx"> 
</span><span class="cx">         SLIST_FOREACH(si, &amp;j-&gt;semaphores, sle) {
</span><span class="cx">                 bool wanted_state = false;
</span><ins>+                int qdir_file_cnt;
+
</ins><span class="cx">                 switch (si-&gt;why) {
</span><span class="cx">                 case NETWORK_UP:
</span><span class="cx">                         wanted_state = true;
</span><span class="lines">@@ -2843,9 +2796,22 @@
</span><span class="cx">                         if ((bool)(stat(si-&gt;what, &amp;sb) == 0) == wanted_state) {
</span><span class="cx">                                 job_log(j, LOG_DEBUG, &quot;KeepAlive check: job configured to run while the following path %s: %s&quot;,
</span><span class="cx">                                                 wanted_state ? &quot;exists&quot; : &quot;is missing&quot;, si-&gt;what);
</span><ins>+                                if (si-&gt;fd != -1) {
+                                        job_assumes(j, close(si-&gt;fd) == 0);
+                                        si-&gt;fd = -1;
+                                }
</ins><span class="cx">                                 return true;
</span><span class="cx">                         }
</span><span class="cx">                         break;
</span><ins>+                case PATH_CHANGES:
+                        break;
+                case DIR_NOT_EMPTY:
+                        if (-1 == (qdir_file_cnt = dir_has_files(j, si-&gt;what))) {
+                                job_log_error(j, LOG_ERR, &quot;dir_has_files(\&quot;%s\&quot;, ...)&quot;, si-&gt;what);
+                        } else if (qdir_file_cnt &gt; 0) {
+                                return true;
+                        }
+                        break;
</ins><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -2928,6 +2894,18 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><ins>+machservice_watch(job_t j, struct machservice *ms)
+{
+        job_assumes(j, runtime_add_mport(ms-&gt;port, NULL, 0) == KERN_SUCCESS);
+}
+
+void
+machservice_ignore(job_t j, struct machservice *ms)
+{
+        job_assumes(j, runtime_remove_mport(ms-&gt;port) == KERN_SUCCESS);
+}
+
+void
</ins><span class="cx"> machservice_resetport(job_t j, struct machservice *ms)
</span><span class="cx"> {
</span><span class="cx">         job_assumes(j, launchd_mport_close_recv(ms-&gt;port) == KERN_SUCCESS);
</span><span class="lines">@@ -3347,7 +3325,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><del>-machservice_watch(struct machservice *ms)
</del><ins>+machservice_request_notifications(struct machservice *ms)
</ins><span class="cx"> {
</span><span class="cx">         mach_msg_id_t which = MACH_NOTIFY_DEAD_NAME;
</span><span class="cx"> 
</span><span class="lines">@@ -3521,6 +3499,7 @@
</span><span class="cx">                 return false;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        si-&gt;fd = -1;
</ins><span class="cx">         si-&gt;why = why;
</span><span class="cx"> 
</span><span class="cx">         if (what) {
</span><span class="lines">@@ -3533,11 +3512,15 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><del>-semaphoreitem_delete(job_t j, struct semaphoreitem *ri)
</del><ins>+semaphoreitem_delete(job_t j, struct semaphoreitem *si)
</ins><span class="cx"> {
</span><del>-        SLIST_REMOVE(&amp;j-&gt;semaphores, ri, semaphoreitem, sle);
</del><ins>+        SLIST_REMOVE(&amp;j-&gt;semaphores, si, semaphoreitem, sle);
</ins><span class="cx"> 
</span><del>-        free(ri);
</del><ins>+        if (si-&gt;fd != -1) {
+                job_assumes(j, close(si-&gt;fd) != -1);
+        }
+
+        free(si);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><span class="lines">@@ -3571,18 +3554,18 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><del>-jobmgr_dispatch_all_other_semaphores(jobmgr_t jm, job_t nj)
</del><ins>+jobmgr_dispatch_all_semaphores(jobmgr_t jm)
</ins><span class="cx"> {
</span><span class="cx">         jobmgr_t jmi;
</span><span class="cx">         job_t ji, jn;
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">         SLIST_FOREACH(jmi, &amp;jm-&gt;submgrs, sle) {
</span><del>-                jobmgr_dispatch_all_other_semaphores(jmi, nj);
</del><ins>+                jobmgr_dispatch_all_semaphores(jmi);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         SLIST_FOREACH_SAFE(ji, &amp;jm-&gt;jobs, sle, jn) {
</span><del>-                if (ji != nj &amp;&amp; !SLIST_EMPTY(&amp;ji-&gt;semaphores)) {
</del><ins>+                if (!SLIST_EMPTY(&amp;ji-&gt;semaphores)) {
</ins><span class="cx">                         job_dispatch(ji, false);
</span><span class="cx">                 }
</span><span class="cx">         }
</span><span class="lines">@@ -3979,7 +3962,7 @@
</span><span class="cx">                 return BOOTSTRAP_SERVICE_ACTIVE;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        machservice_watch(ms);
</del><ins>+        machservice_request_notifications(ms);
</ins><span class="cx"> 
</span><span class="cx">         job_log(j, LOG_INFO, &quot;Check-in of service: %s&quot;, servicename);
</span><span class="cx"> 
</span><span class="lines">@@ -4034,7 +4017,7 @@
</span><span class="cx"> 
</span><span class="cx">         if (serviceport != MACH_PORT_NULL) {
</span><span class="cx">                 if ((ms = machservice_new(j, servicename, &amp;serviceport))) {
</span><del>-                        machservice_watch(ms);
</del><ins>+                        machservice_request_notifications(ms);
</ins><span class="cx">                 } else {
</span><span class="cx">                         return BOOTSTRAP_NO_MEMORY;
</span><span class="cx">                 }
</span><span class="lines">@@ -4228,7 +4211,7 @@
</span><span class="cx">                 struct machservice *ms;
</span><span class="cx"> 
</span><span class="cx">                 if ((ms = machservice_new(jmr-&gt;anonj, l2l_names[l2l_i], &amp;l2l_ports[l2l_i]))) {
</span><del>-                        machservice_watch(ms);
</del><ins>+                        machservice_request_notifications(ms);
</ins><span class="cx">                 }
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunklaunchdsrclaunchd_core_logich"></a>
<div class="modfile"><h4>Modified: trunk/launchd/src/launchd_core_logic.h (23008 => 23009)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/launchd/src/launchd_core_logic.h        2007-01-10 21:58:22 UTC (rev 23008)
+++ trunk/launchd/src/launchd_core_logic.h        2007-01-12 00:33:20 UTC (rev 23009)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> void jobmgr_set_stderr(jobmgr_t jm, const char *what);
</span><span class="cx"> bool jobmgr_is_idle(jobmgr_t jm);
</span><span class="cx"> void jobmgr_remove_all_inactive(jobmgr_t jm);
</span><del>-void jobmgr_dispatch_all_other_semaphores(jobmgr_t jm, job_t nj);
</del><ins>+void jobmgr_dispatch_all_semaphores(jobmgr_t jm);
</ins><span class="cx"> job_t jobmgr_find(jobmgr_t jm, const char *label);
</span><span class="cx"> void jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port);
</span><span class="cx"> bool jobmgr_ack_port_destruction(jobmgr_t jm, mach_port_t p);
</span></span></pre>
</div>
</div>

</body>
</html>