Changeset 23042
- Timestamp:
- 02/08/07 07:21:26 (22 months ago)
- Location:
- trunk/launchd/src
- Files:
-
- 6 modified
-
launchd.c (modified) (3 diffs)
-
launchd.h (modified) (1 diff)
-
launchd.plist.5 (modified) (1 diff)
-
launchd_core_logic.c (modified) (12 diffs)
-
launchd_core_logic.h (modified) (1 diff)
-
liblaunch_public.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/launchd/src/launchd.c
r23041 r23042 111 111 112 112 sigset_t blocked_signals = 0; 113 bool shutdown_in_progress = false;113 static bool shutdown_in_progress = false; 114 114 bool debug_shutdown_hangs = false; 115 115 bool network_up = false; … … 470 470 rlcj = NULL; 471 471 472 jobmgr_remove_all_inactive(root_jobmgr);472 root_jobmgr = jobmgr_shutdown(root_jobmgr); 473 473 } 474 474 … … 677 677 launchd_post_kevent(void) 678 678 { 679 if (shutdown_in_progress && jobmgr_is_idle(root_jobmgr)) {679 if (shutdown_in_progress && (!root_jobmgr || jobmgr_is_idle(root_jobmgr))) { 680 680 shutdown_in_progress = false; 681 681 -
trunk/launchd/src/launchd.h
r23025 r23042 35 35 extern kq_callback kqsimple_zombie_reaper; 36 36 extern sigset_t blocked_signals; 37 extern bool shutdown_in_progress;38 37 extern bool debug_shutdown_hangs; 39 38 extern bool network_up; -
trunk/launchd/src/launchd.plist.5
r23040 r23042 272 272 .Xr nice 3 273 273 value should be applied to the daemon. 274 .It Sy HopefullyExitsLast <boolean> 275 This optional key causes programs to exit in a second wave during system 276 shutdown. This key exists because some jobs don't reference count their 277 clients, and therefore do not know when it is safe to exit. The use of this key 278 should be considered a temporary solution until the software can be changed to 279 properly reference count clients. 274 280 .It Sy LowPriorityIO <boolean> 275 281 This optional key specifies whether the kernel should consider this daemon to be low priority when doing file system I/O. -
trunk/launchd/src/launchd_core_logic.c
r23040 r23042 200 200 char *jm_stderr; 201 201 unsigned int global_on_demand_cnt; 202 unsigned int transfer_bstrap:1 ;202 unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1; 203 203 char name[0]; 204 204 }; … … 209 209 static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t checkin_port); 210 210 static jobmgr_t jobmgr_parent(jobmgr_t jm); 211 static jobmgr_t jobmgr_tickle(jobmgr_t jm); 211 212 static void jobmgr_dispatch_all(jobmgr_t jm); 212 213 static job_t jobmgr_new_anonymous(jobmgr_t jm); … … 269 270 mode_t mask; 270 271 unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1, 271 currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1 ;272 currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1; 272 273 char label[0]; 273 274 }; … … 511 512 } 512 513 513 void 514 jobmgr_ remove_all_inactive(jobmgr_t jm)514 jobmgr_t 515 jobmgr_shutdown(jobmgr_t jm) 515 516 { 516 517 jobmgr_t jmi, jmn; … … 518 519 519 520 SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { 520 jobmgr_ remove_all_inactive(jmi);521 jobmgr_shutdown(jmi); 521 522 } 522 523 … … 524 525 if (!job_active(ji)) { 525 526 job_remove(ji); 526 } else {527 } else if (!ji->hopefully_exits_last) { 527 528 job_stop(ji); 528 529 } 529 530 } 531 532 jm->shutting_down = true; 533 534 return jobmgr_tickle(jm); 530 535 } 531 536 … … 596 601 } 597 602 603 if (j->forkfd) { 604 job_assumes(j, close(j->forkfd) != -1); 605 } 606 607 if (j->log_redirect_fd) { 608 job_assumes(j, close(j->log_redirect_fd) != -1); 609 } 610 611 if (j->j_port) { 612 job_assumes(j, launchd_mport_close_recv(j->j_port) == KERN_SUCCESS); 613 } 614 615 if (!job_assumes(j, j->wait_reply_port == MACH_PORT_NULL)) { 616 job_assumes(j, launchd_mport_deallocate(j->wait_reply_port) == KERN_SUCCESS); 617 } 618 619 while ((sg = SLIST_FIRST(&j->sockets))) { 620 socketgroup_delete(j, sg); 621 } 622 while ((ci = SLIST_FIRST(&j->cal_intervals))) { 623 calendarinterval_delete(j, ci); 624 } 625 while ((ei = SLIST_FIRST(&j->env))) { 626 envitem_delete(j, ei, false); 627 } 628 while ((ei = SLIST_FIRST(&j->global_env))) { 629 envitem_delete(j, ei, true); 630 } 631 while ((li = SLIST_FIRST(&j->limits))) { 632 limititem_delete(j, li); 633 } 634 while ((ms = SLIST_FIRST(&j->machservices))) { 635 machservice_delete(ms); 636 } 637 while ((si = SLIST_FIRST(&j->semaphores))) { 638 semaphoreitem_delete(j, si); 639 } 640 641 if (j->prog) { 642 free(j->prog); 643 } 644 if (j->argv) { 645 free(j->argv); 646 } 647 if (j->rootdir) { 648 free(j->rootdir); 649 } 650 if (j->workingdir) { 651 free(j->workingdir); 652 } 653 if (j->username) { 654 free(j->username); 655 } 656 if (j->groupname) { 657 free(j->groupname); 658 } 659 if (j->stdinpath) { 660 free(j->stdinpath); 661 } 662 if (j->stdoutpath) { 663 free(j->stdoutpath); 664 } 665 if (j->stderrpath) { 666 free(j->stderrpath); 667 } 668 if (j->start_interval) { 669 job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); 670 } 671 if (j->exit_timeout) { 672 kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 673 } 674 675 kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 676 598 677 if (job_assumes(j, j->mgr)) { 599 678 SLIST_REMOVE(&j->mgr->jobs, j, job_s, sle); 600 } 601 602 if (j->forkfd) { 603 job_assumes(j, close(j->forkfd) != -1); 604 } 605 606 if (j->log_redirect_fd) { 607 job_assumes(j, close(j->log_redirect_fd) != -1); 608 } 609 610 if (j->j_port) { 611 job_assumes(j, launchd_mport_close_recv(j->j_port) == KERN_SUCCESS); 612 } 613 614 if (!job_assumes(j, j->wait_reply_port == MACH_PORT_NULL)) { 615 job_assumes(j, launchd_mport_deallocate(j->wait_reply_port) == KERN_SUCCESS); 616 } 617 618 while ((sg = SLIST_FIRST(&j->sockets))) { 619 socketgroup_delete(j, sg); 620 } 621 while ((ci = SLIST_FIRST(&j->cal_intervals))) { 622 calendarinterval_delete(j, ci); 623 } 624 while ((ei = SLIST_FIRST(&j->env))) { 625 envitem_delete(j, ei, false); 626 } 627 while ((ei = SLIST_FIRST(&j->global_env))) { 628 envitem_delete(j, ei, true); 629 } 630 while ((li = SLIST_FIRST(&j->limits))) { 631 limititem_delete(j, li); 632 } 633 while ((ms = SLIST_FIRST(&j->machservices))) { 634 machservice_delete(ms); 635 } 636 while ((si = SLIST_FIRST(&j->semaphores))) { 637 semaphoreitem_delete(j, si); 638 } 639 640 if (j->prog) { 641 free(j->prog); 642 } 643 if (j->argv) { 644 free(j->argv); 645 } 646 if (j->rootdir) { 647 free(j->rootdir); 648 } 649 if (j->workingdir) { 650 free(j->workingdir); 651 } 652 if (j->username) { 653 free(j->username); 654 } 655 if (j->groupname) { 656 free(j->groupname); 657 } 658 if (j->stdinpath) { 659 free(j->stdinpath); 660 } 661 if (j->stdoutpath) { 662 free(j->stdoutpath); 663 } 664 if (j->stderrpath) { 665 free(j->stderrpath); 666 } 667 if (j->start_interval) { 668 job_assumes(j, kevent_mod((uintptr_t)&j->start_interval, EVFILT_TIMER, EV_DELETE, 0, 0, NULL) != -1); 669 } 670 if (j->exit_timeout) { 671 kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 672 } 673 674 kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 679 jobmgr_tickle(j->mgr); 680 } 681 675 682 free(j); 676 683 } … … 895 902 job_t j; 896 903 897 if ( shutdown_in_progress) {904 if (jm->shutting_down) { 898 905 errno = EINVAL; 899 906 return NULL; … … 1035 1042 if (strcasecmp(key, LAUNCH_JOBKEY_DEBUG) == 0) { 1036 1043 j->debug = value; 1044 } 1045 break; 1046 case 'h': 1047 case 'H': 1048 if (strcasecmp(key, LAUNCH_JOBKEY_HOPEFULLYEXITSLAST) == 0) { 1049 j->hopefully_exits_last = value; 1037 1050 } 1038 1051 break; … … 2806 2819 job_log(j, LOG_INFO, "Exited. Was only configured to run once."); 2807 2820 return true; 2808 } else if ( shutdown_in_progress) {2821 } else if (j->mgr->shutting_down) { 2809 2822 job_log(j, LOG_INFO, "Exited while shutdown in progress."); 2810 2823 return true; … … 3163 3176 } 3164 3177 3178 jobmgr_t 3179 jobmgr_tickle(jobmgr_t jm) 3180 { 3181 job_t ji; 3182 3183 if (jm->sent_stop_to_hopeful_jobs || !jm->shutting_down) { 3184 return jm; 3185 } 3186 3187 SLIST_FOREACH(ji, &jm->jobs, sle) { 3188 if (ji->p && !ji->hopefully_exits_last) { 3189 return jm; 3190 } 3191 } 3192 3193 SLIST_FOREACH(ji, &jm->jobs, sle) { 3194 job_stop(ji); 3195 } 3196 3197 jm->sent_stop_to_hopeful_jobs = true; 3198 3199 if (jobmgr_is_idle(jm)) { 3200 jobmgr_remove(jm); 3201 return NULL; 3202 } 3203 3204 return jm; 3205 } 3206 3165 3207 bool 3166 3208 jobmgr_is_idle(jobmgr_t jm) … … 3322 3364 3323 3365 if (jm->req_port == port) { 3324 if (jm == root_jobmgr) { 3325 launchd_shutdown(); 3326 } else { 3327 return jobmgr_remove(jm); 3328 } 3366 jobmgr_shutdown(jm); 3329 3367 } 3330 3368 -
trunk/launchd/src/launchd_core_logic.h
r23037 r23042 33 33 void jobmgr_set_stderr(jobmgr_t jm, const char *what); 34 34 bool jobmgr_is_idle(jobmgr_t jm); 35 void jobmgr_remove_all_inactive(jobmgr_t jm);35 jobmgr_t jobmgr_shutdown(jobmgr_t jm); 36 36 void jobmgr_dispatch_all_semaphores(jobmgr_t jm); 37 37 job_t jobmgr_find(jobmgr_t jm, const char *label); -
trunk/launchd/src/liblaunch_public.h
r23040 r23042 79 79 #define LAUNCH_JOBKEY_UMASK "Umask" 80 80 #define LAUNCH_JOBKEY_NICE "Nice" 81 #define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST "HopefullyExitsLast" 81 82 #define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" 82 83 #define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate"

