Changeset 23274
- Timestamp:
- 06/07/07 16:00:50 (18 months ago)
- Location:
- trunk/launchd/src
- Files:
-
- 8 modified
-
launchd.c (modified) (2 diffs)
-
launchd.h (modified) (1 diff)
-
launchd_core_logic.c (modified) (11 diffs)
-
launchd_runtime.c (modified) (6 diffs)
-
launchd_runtime.h (modified) (1 diff)
-
launchd_unix_ipc.c (modified) (3 diffs)
-
launchd_unix_ipc.h (modified) (1 diff)
-
liblaunch.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/launchd/src/launchd.c
r23186 r23274 103 103 bool debug_shutdown_hangs = false; 104 104 bool network_up = false; 105 int batch_disabler_count = 0;106 105 107 106 int … … 316 315 } 317 316 318 void319 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 336 317 bool 337 318 get_network_state(void) -
trunk/launchd/src/launchd.h
r23082 r23274 34 34 extern bool debug_shutdown_hangs; 35 35 extern bool network_up; 36 extern int batch_disabler_count;37 36 extern mach_port_t inherited_bootstrap_port; 38 37 39 38 bool init_check_pid(pid_t); 40 41 void batch_job_enable(bool e, struct conncb *c);42 39 43 40 launch_data_t launchd_setstdio(int d, launch_data_t o); -
trunk/launchd/src/launchd_core_logic.c
r23272 r23274 336 336 unsigned int checkedin:1, anonymous:1, debug:1, inetcompat:1, inetcompat_wait:1, 337 337 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; 339 339 mode_t mask; 340 340 unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1, … … 1225 1225 case 'R': 1226 1226 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 } 1228 1231 found_key = true; 1229 1232 } … … 1943 1946 1944 1947 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); 1946 1953 } 1947 1954 } … … 2068 2075 job_callback_timer(job_t j, void *ident) 2069 2076 { 2070 if (j == ident || &j->start_interval == ident) {2077 if (j == ident) { 2071 2078 job_dispatch(j, true); 2079 } else if (&j->start_interval == ident) { 2080 j->start_pending = true; 2081 job_dispatch(j, false); 2072 2082 } else if (&j->exit_timeout == ident) { 2073 2083 if (j->sent_sigkill) { … … 2263 2273 job_log(j, LOG_DEBUG, "Started as PID: %u", c); 2264 2274 2275 j->start_pending = false; 2276 2265 2277 total_children++; 2266 2278 LIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle); … … 2995 3007 job_log(j, LOG_DEBUG, "Watch path modified: %s", si->what); 2996 3008 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 3016 static void 3017 calendarinterval_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 } 2998 3042 } 2999 3043 … … 3001 3045 calendarinterval_new_from_obj(job_t j, launch_data_t obj) 3002 3046 { 3003 launch_data_t tmp_k;3004 3047 struct tm tmptm; 3005 3048 … … 3020 3063 } 3021 3064 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; 3037 3069 } 3038 3070 … … 3081 3113 if (job_assumes(j, ci != NULL)) { 3082 3114 calendarinterval_setalarm(j, ci); 3083 job_dispatch(j, true); 3115 j->start_pending = true; 3116 job_dispatch(j, false); 3084 3117 } 3085 3118 } … … 3356 3389 } 3357 3390 3358 if (j-> runatload&& j->start_time == 0) {3391 if (j->start_pending && j->start_time == 0) { 3359 3392 job_log(j, LOG_DEBUG, "KeepAlive check: job needs to run at least once."); 3360 3393 return true; … … 4361 4394 why = launch_data_get_bool(obj) ? SUCCESSFUL_EXIT : FAILED_EXIT; 4362 4395 semaphoreitem_new(j, why, NULL); 4363 j-> runatload= true;4396 j->start_pending = true; 4364 4397 } else { 4365 4398 job_assumes(j, false); -
trunk/launchd/src/launchd_runtime.c
r23259 r23274 70 70 static mach_port_t launchd_internal_port; 71 71 static int mainkq; 72 static int asynckq;73 72 74 73 #define BULK_KEV_MAX 100 … … 83 82 static void *kqueue_demand_loop(void *arg); 84 83 static 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;88 84 89 85 static void record_caller_creds(mach_msg_header_t *mh); … … 103 99 104 100 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);108 101 109 102 launchd_assert((errno = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &demand_port_set)) == KERN_SUCCESS); … … 692 685 { 693 686 struct kevent kev; 694 int q = mainkq;695 687 696 688 switch (filter) { … … 698 690 case EVFILT_WRITE: 699 691 break; 700 case EVFILT_TIMER:701 case EVFILT_VNODE:702 case EVFILT_FS:703 q = asynckq;704 /* fall through */705 692 default: 706 693 flags |= EV_CLEAR; … … 715 702 EV_SET(&kev, ident, filter, flags, fflags, data, udata); 716 703 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); 736 705 } 737 706 -
trunk/launchd/src/launchd_runtime.h
r23250 r23274 62 62 int runtime_close(int fd); 63 63 64 void runtime_force_on_demand(bool);65 64 void runtime_set_timeout(timeout_callback to_cb, mach_msg_timeout_t to); 66 65 kern_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 370 370 getrusage(RUSAGE_CHILDREN, &rusage); 371 371 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);375 372 } 376 373 } else if (!strcmp(cmd, LAUNCH_KEY_STARTJOB)) { … … 416 413 ipc_revoke_fds(resp); 417 414 } 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);421 415 } 422 416 … … 427 421 ipc_close(struct conncb *c) 428 422 { 429 batch_job_enable(true, c);430 431 423 LIST_REMOVE(c, sle); 432 424 launchd_close(c->conn, runtime_close); -
trunk/launchd/src/launchd_unix_ipc.h
r23186 r23274 32 32 launch_t conn; 33 33 job_t j; 34 int disabled_batch:1, futureflags:31;35 34 }; 36 35 -
trunk/launchd/src/liblaunch.c
r23268 r23274 1068 1068 } 1069 1069 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; 1070 void 1071 launchd_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 1078 bool 1079 launchd_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; 1105 1088 } 1106 1089

