Projects
Browse Source     Search     Timeline     Wiki

Changeset 23042

Show
Ignore:
Timestamp:
02/08/07 07:21:26 (22 months ago)
Author:
zarzycki@…
Message:

<rdar://problem/4943031> Add plist option to mimic the kernel's KERN_PROCDELAYTERM

Location:
trunk/launchd/src
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/launchd/src/launchd.c

    r23041 r23042  
    111111 
    112112sigset_t blocked_signals = 0; 
    113 bool shutdown_in_progress = false; 
     113static bool shutdown_in_progress = false; 
    114114bool debug_shutdown_hangs = false; 
    115115bool network_up = false; 
     
    470470        rlcj = NULL; 
    471471 
    472         jobmgr_remove_all_inactive(root_jobmgr); 
     472        root_jobmgr = jobmgr_shutdown(root_jobmgr); 
    473473} 
    474474 
     
    677677launchd_post_kevent(void) 
    678678{ 
    679         if (shutdown_in_progress && jobmgr_is_idle(root_jobmgr)) { 
     679        if (shutdown_in_progress && (!root_jobmgr || jobmgr_is_idle(root_jobmgr))) { 
    680680                shutdown_in_progress = false; 
    681681 
  • trunk/launchd/src/launchd.h

    r23025 r23042  
    3535extern kq_callback kqsimple_zombie_reaper; 
    3636extern sigset_t blocked_signals; 
    37 extern bool shutdown_in_progress; 
    3837extern bool debug_shutdown_hangs; 
    3938extern bool network_up; 
  • trunk/launchd/src/launchd.plist.5

    r23040 r23042  
    272272.Xr nice 3 
    273273value should be applied to the daemon. 
     274.It Sy HopefullyExitsLast <boolean> 
     275This optional key causes programs to exit in a second wave during system 
     276shutdown. This key exists because some jobs don't reference count their 
     277clients, and therefore do not know when it is safe to exit. The use of this key 
     278should be considered a temporary solution until the software can be changed to 
     279properly reference count clients. 
    274280.It Sy LowPriorityIO <boolean> 
    275281This 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  
    200200        char *jm_stderr; 
    201201        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; 
    203203        char name[0]; 
    204204}; 
     
    209209static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t checkin_port); 
    210210static jobmgr_t jobmgr_parent(jobmgr_t jm); 
     211static jobmgr_t jobmgr_tickle(jobmgr_t jm); 
    211212static void jobmgr_dispatch_all(jobmgr_t jm); 
    212213static job_t jobmgr_new_anonymous(jobmgr_t jm); 
     
    269270        mode_t mask; 
    270271        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; 
    272273        char label[0]; 
    273274}; 
     
    511512} 
    512513 
    513 void 
    514 jobmgr_remove_all_inactive(jobmgr_t jm) 
     514jobmgr_t 
     515jobmgr_shutdown(jobmgr_t jm) 
    515516{ 
    516517        jobmgr_t jmi, jmn; 
     
    518519 
    519520        SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) { 
    520                 jobmgr_remove_all_inactive(jmi); 
     521                jobmgr_shutdown(jmi); 
    521522        } 
    522523 
     
    524525                if (!job_active(ji)) { 
    525526                        job_remove(ji); 
    526                 } else { 
     527                } else if (!ji->hopefully_exits_last) { 
    527528                        job_stop(ji); 
    528529                } 
    529530        } 
     531 
     532        jm->shutting_down = true; 
     533 
     534        return jobmgr_tickle(jm); 
    530535} 
    531536 
     
    596601        } 
    597602 
     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 
    598677        if (job_assumes(j, j->mgr)) { 
    599678                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 
    675682        free(j); 
    676683} 
     
    895902        job_t j; 
    896903 
    897         if (shutdown_in_progress) { 
     904        if (jm->shutting_down) { 
    898905                errno = EINVAL; 
    899906                return NULL; 
     
    10351042                if (strcasecmp(key, LAUNCH_JOBKEY_DEBUG) == 0) { 
    10361043                        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; 
    10371050                } 
    10381051                break; 
     
    28062819                job_log(j, LOG_INFO, "Exited. Was only configured to run once."); 
    28072820                return true; 
    2808         } else if (shutdown_in_progress) { 
     2821        } else if (j->mgr->shutting_down) { 
    28092822                job_log(j, LOG_INFO, "Exited while shutdown in progress."); 
    28102823                return true; 
     
    31633176} 
    31643177 
     3178jobmgr_t 
     3179jobmgr_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 
    31653207bool 
    31663208jobmgr_is_idle(jobmgr_t jm) 
     
    33223364 
    33233365        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); 
    33293367        } 
    33303368 
  • trunk/launchd/src/launchd_core_logic.h

    r23037 r23042  
    3333void jobmgr_set_stderr(jobmgr_t jm, const char *what); 
    3434bool jobmgr_is_idle(jobmgr_t jm); 
    35 void jobmgr_remove_all_inactive(jobmgr_t jm); 
     35jobmgr_t jobmgr_shutdown(jobmgr_t jm); 
    3636void jobmgr_dispatch_all_semaphores(jobmgr_t jm); 
    3737job_t jobmgr_find(jobmgr_t jm, const char *label); 
  • trunk/launchd/src/liblaunch_public.h

    r23040 r23042  
    7979#define LAUNCH_JOBKEY_UMASK                     "Umask" 
    8080#define LAUNCH_JOBKEY_NICE                      "Nice" 
     81#define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST        "HopefullyExitsLast" 
    8182#define LAUNCH_JOBKEY_LOWPRIORITYIO             "LowPriorityIO" 
    8283#define LAUNCH_JOBKEY_SESSIONCREATE             "SessionCreate"