Projects
Browse Source     Search     Timeline     Wiki

Changeset 23274

Show
Ignore:
Timestamp:
06/07/07 16:00:50 (18 months ago)
Author:
zarzycki@…
Message:

<rdar://problem/5257979> merge launchd's two kqueues into one

Location:
trunk/launchd/src
Files:
8 modified

Legend:

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

    r23186 r23274  
    103103bool debug_shutdown_hangs = false; 
    104104bool network_up = false; 
    105 int batch_disabler_count = 0; 
    106105 
    107106int 
     
    316315} 
    317316 
    318 void 
    319 batch_job_enable(bool e, struct conncb *c) 
    320 { 
    321         if (e && c->disabled_batch) { 
    322                 batch_disabler_count--; 
    323                 c->disabled_batch = 0; 
    324                 if (batch_disabler_count == 0) { 
    325                         runtime_force_on_demand(false); 
    326                 } 
    327         } else if (!e && !c->disabled_batch) { 
    328                 if (batch_disabler_count == 0) { 
    329                         runtime_force_on_demand(true); 
    330                 } 
    331                 batch_disabler_count++; 
    332                 c->disabled_batch = 1; 
    333         } 
    334 } 
    335  
    336317bool 
    337318get_network_state(void) 
  • trunk/launchd/src/launchd.h

    r23082 r23274  
    3434extern bool debug_shutdown_hangs; 
    3535extern bool network_up; 
    36 extern int batch_disabler_count; 
    3736extern mach_port_t inherited_bootstrap_port; 
    3837 
    3938bool init_check_pid(pid_t); 
    40  
    41 void batch_job_enable(bool e, struct conncb *c); 
    4239 
    4340launch_data_t launchd_setstdio(int d, launch_data_t o); 
  • trunk/launchd/src/launchd_core_logic.c

    r23272 r23274  
    336336        unsigned int checkedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1, 
    337337                     ondemand:1, session_create:1, low_pri_io:1, no_init_groups:1, priv_port_has_senders:1, 
    338                      importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, runatload:1; 
     338                     importing_global_env:1, importing_hard_limits:1, setmask:1, legacy_mach_job:1, start_pending:1; 
    339339        mode_t mask; 
    340340        unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1, 
     
    12251225        case 'R': 
    12261226                if (strcasecmp(key, LAUNCH_JOBKEY_RUNATLOAD) == 0) { 
    1227                         j->runatload = value; 
     1227                        if (value) { 
     1228                                /* We don't want value == false to change j->start_pending */ 
     1229                                j->start_pending = true; 
     1230                        } 
    12281231                        found_key = true; 
    12291232                } 
     
    19431946 
    19441947        LIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) { 
    1945                 job_dispatch(ji, newmounthack ? ji->start_on_mount : false); 
     1948                if (newmounthack && ji->start_on_mount) { 
     1949                        ji->start_pending = true; 
     1950                } 
     1951 
     1952                job_dispatch(ji, false); 
    19461953        } 
    19471954} 
     
    20682075job_callback_timer(job_t j, void *ident) 
    20692076{ 
    2070         if (j == ident || &j->start_interval == ident) { 
     2077        if (j == ident) { 
    20712078                job_dispatch(j, true); 
     2079        } else if (&j->start_interval == ident) { 
     2080                j->start_pending = true; 
     2081                job_dispatch(j, false); 
    20722082        } else if (&j->exit_timeout == ident) { 
    20732083                if (j->sent_sigkill) { 
     
    22632273                job_log(j, LOG_DEBUG, "Started as PID: %u", c); 
    22642274 
     2275                j->start_pending = false; 
     2276 
    22652277                total_children++; 
    22662278                LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); 
     
    29953007        job_log(j, LOG_DEBUG, "Watch path modified: %s", si->what); 
    29963008 
    2997         job_dispatch(j, si->why == PATH_CHANGES ? true : false); 
     3009        if (si->why == PATH_CHANGES) { 
     3010                j->start_pending = true; 
     3011        } 
     3012 
     3013        job_dispatch(j, false); 
     3014} 
     3015 
     3016static void 
     3017calendarinterval_new_from_obj_dict_walk(launch_data_t obj, const char *key, void *context) 
     3018{ 
     3019        struct tm *tmptm = context; 
     3020        int64_t val; 
     3021 
     3022        if (LAUNCH_DATA_INTEGER != launch_data_get_type(obj)) { 
     3023                /* hack to let caller know something went wrong */ 
     3024                tmptm->tm_sec = -1; 
     3025                return; 
     3026        } 
     3027 
     3028        val = launch_data_get_integer(obj); 
     3029 
     3030        if (strcasecmp(key, LAUNCH_JOBKEY_CAL_MINUTE) == 0) { 
     3031                tmptm->tm_min = val; 
     3032        } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_HOUR) == 0) { 
     3033                tmptm->tm_hour = val; 
     3034        } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_DAY) == 0) { 
     3035                tmptm->tm_mday = val; 
     3036        } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_WEEKDAY) == 0) { 
     3037                tmptm->tm_wday = val; 
     3038        } else if (strcasecmp(key, LAUNCH_JOBKEY_CAL_MONTH) == 0) { 
     3039                tmptm->tm_mon = val; 
     3040                tmptm->tm_mon -= 1; /* 4798263 cron compatibility */ 
     3041        } 
    29983042} 
    29993043 
     
    30013045calendarinterval_new_from_obj(job_t j, launch_data_t obj) 
    30023046{ 
    3003         launch_data_t tmp_k; 
    30043047        struct tm tmptm; 
    30053048 
     
    30203063        } 
    30213064 
    3022         if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_MINUTE))) { 
    3023                 tmptm.tm_min = launch_data_get_integer(tmp_k); 
    3024         } 
    3025         if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_HOUR))) { 
    3026                 tmptm.tm_hour = launch_data_get_integer(tmp_k); 
    3027         } 
    3028         if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_DAY))) { 
    3029                 tmptm.tm_mday = launch_data_get_integer(tmp_k); 
    3030         } 
    3031         if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_WEEKDAY))) { 
    3032                 tmptm.tm_wday = launch_data_get_integer(tmp_k); 
    3033         } 
    3034         if ((tmp_k = launch_data_dict_lookup(obj, LAUNCH_JOBKEY_CAL_MONTH))) { 
    3035                 tmptm.tm_mon = launch_data_get_integer(tmp_k); 
    3036                 tmptm.tm_mon -= 1; /* 4798263 cron compatibility */ 
     3065        launch_data_dict_iterate(obj, calendarinterval_new_from_obj_dict_walk, &tmptm); 
     3066 
     3067        if (tmptm.tm_sec == -1) { 
     3068                return false; 
    30373069        } 
    30383070 
     
    30813113        if (job_assumes(j, ci != NULL)) { 
    30823114                calendarinterval_setalarm(j, ci); 
    3083                 job_dispatch(j, true); 
     3115                j->start_pending = true; 
     3116                job_dispatch(j, false); 
    30843117        } 
    30853118} 
     
    33563389        } 
    33573390 
    3358         if (j->runatload && j->start_time == 0) { 
     3391        if (j->start_pending && j->start_time == 0) { 
    33593392                job_log(j, LOG_DEBUG, "KeepAlive check: job needs to run at least once."); 
    33603393                return true; 
     
    43614394                        why = launch_data_get_bool(obj) ? SUCCESSFUL_EXIT : FAILED_EXIT; 
    43624395                        semaphoreitem_new(j, why, NULL); 
    4363                         j->runatload = true; 
     4396                        j->start_pending = true; 
    43644397                } else { 
    43654398                        job_assumes(j, false); 
  • trunk/launchd/src/launchd_runtime.c

    r23259 r23274  
    7070static mach_port_t launchd_internal_port; 
    7171static int mainkq; 
    72 static int asynckq; 
    7372 
    7473#define BULK_KEV_MAX 100 
     
    8382static void *kqueue_demand_loop(void *arg); 
    8483static void log_kevent_struct(int level, struct kevent *kev, int indx); 
    85  
    86 static void async_callback(void); 
    87 static kq_callback kqasync_callback = (kq_callback)async_callback; 
    8884 
    8985static void record_caller_creds(mach_msg_header_t *mh); 
     
    10399 
    104100        launchd_assert((mainkq = kqueue()) != -1); 
    105         launchd_assert((asynckq = kqueue()) != -1); 
    106  
    107         launchd_assert(kevent_mod(asynckq, EVFILT_READ, EV_ADD, 0, 0, &kqasync_callback) != -1); 
    108101 
    109102        launchd_assert((errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &demand_port_set)) == KERN_SUCCESS); 
     
    692685{ 
    693686        struct kevent kev; 
    694         int q = mainkq; 
    695687 
    696688        switch (filter) { 
     
    698690        case EVFILT_WRITE: 
    699691                break; 
    700         case EVFILT_TIMER: 
    701         case EVFILT_VNODE: 
    702         case EVFILT_FS: 
    703                 q = asynckq; 
    704                 /* fall through */ 
    705692        default: 
    706693                flags |= EV_CLEAR; 
     
    715702        EV_SET(&kev, ident, filter, flags, fflags, data, udata); 
    716703 
    717         return kevent(q, &kev, 1, NULL, 0, NULL); 
    718 } 
    719  
    720 void 
    721 async_callback(void) 
    722 { 
    723         struct timespec timeout = { 0, 0 }; 
    724         struct kevent kev; 
    725  
    726         if (launchd_assumes(kevent(asynckq, NULL, 0, &kev, 1, &timeout) == 1)) { 
    727                 log_kevent_struct(LOG_DEBUG, &kev, 0); 
    728                 (*((kq_callback *)kev.udata))(kev.udata, &kev); 
    729         } 
    730 } 
    731  
    732 void 
    733 runtime_force_on_demand(bool b) 
    734 { 
    735         launchd_assumes(kevent_mod(asynckq, EVFILT_READ, b ? EV_DISABLE : EV_ENABLE, 0, 0, &kqasync_callback) != -1); 
     704        return kevent(mainkq, &kev, 1, NULL, 0, NULL); 
    736705} 
    737706 
  • trunk/launchd/src/launchd_runtime.h

    r23250 r23274  
    6262int runtime_close(int fd); 
    6363 
    64 void runtime_force_on_demand(bool); 
    6564void runtime_set_timeout(timeout_callback to_cb, mach_msg_timeout_t to); 
    6665kern_return_t runtime_add_mport(mach_port_t name, mig_callback demux, mach_msg_size_t msg_size); 
  • trunk/launchd/src/launchd_unix_ipc.c

    r23235 r23274  
    370370                        getrusage(RUSAGE_CHILDREN, &rusage); 
    371371                        resp = launch_data_new_opaque(&rusage, sizeof(rusage)); 
    372                 } else if (!strcmp(cmd, LAUNCH_KEY_BATCHQUERY)) { 
    373                         resp = launch_data_alloc(LAUNCH_DATA_BOOL); 
    374                         launch_data_set_bool(resp, batch_disabler_count == 0); 
    375372                } 
    376373        } else if (!strcmp(cmd, LAUNCH_KEY_STARTJOB)) { 
     
    416413                        ipc_revoke_fds(resp); 
    417414                } 
    418         } else if (!strcmp(cmd, LAUNCH_KEY_BATCHCONTROL)) { 
    419                 batch_job_enable(launch_data_get_bool(data), rmc->c); 
    420                 resp = launch_data_new_errno(0); 
    421415        } 
    422416 
     
    427421ipc_close(struct conncb *c) 
    428422{ 
    429         batch_job_enable(true, c); 
    430  
    431423        LIST_REMOVE(c, sle); 
    432424        launchd_close(c->conn, runtime_close); 
  • trunk/launchd/src/launchd_unix_ipc.h

    r23186 r23274  
    3232        launch_t conn; 
    3333        job_t j; 
    34         int disabled_batch:1, futureflags:31; 
    3534}; 
    3635 
  • trunk/launchd/src/liblaunch.c

    r23268 r23274  
    10681068} 
    10691069 
    1070 void launchd_batch_enable(bool val) 
    1071 { 
    1072         launch_data_t resp, tmp, msg; 
    1073  
    1074         tmp = launch_data_alloc(LAUNCH_DATA_BOOL); 
    1075         launch_data_set_bool(tmp, val); 
    1076  
    1077         msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); 
    1078         launch_data_dict_insert(msg, tmp, LAUNCH_KEY_BATCHCONTROL); 
    1079  
    1080         resp = launch_msg(msg); 
    1081  
    1082         launch_data_free(msg); 
    1083  
    1084         if (resp) 
    1085                 launch_data_free(resp); 
    1086 } 
    1087  
    1088 bool launchd_batch_query(void) 
    1089 { 
    1090         launch_data_t resp, msg = launch_data_alloc(LAUNCH_DATA_STRING); 
    1091         bool rval = true; 
    1092  
    1093         launch_data_set_string(msg, LAUNCH_KEY_BATCHQUERY); 
    1094  
    1095         resp = launch_msg(msg); 
    1096  
    1097         launch_data_free(msg); 
    1098  
    1099         if (resp) { 
    1100                 if (launch_data_get_type(resp) == LAUNCH_DATA_BOOL) 
    1101                         rval = launch_data_get_bool(resp); 
    1102                 launch_data_free(resp); 
    1103         } 
    1104         return rval; 
     1070void 
     1071launchd_batch_enable(bool b) 
     1072{ 
     1073        int64_t val = b; 
     1074 
     1075        vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_ON_DEMAND, &val, NULL); 
     1076} 
     1077 
     1078bool 
     1079launchd_batch_query(void) 
     1080{ 
     1081        int64_t val; 
     1082 
     1083        if (vproc_swap_integer(NULL, VPROC_GSK_GLOBAL_ON_DEMAND, NULL, &val) == NULL) { 
     1084                return (bool)val; 
     1085        } 
     1086 
     1087        return false; 
    11051088} 
    11061089