[launchd-changes] [23937] branches/PR-7178164/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 7 17:53:10 PDT 2009


Revision: 23937
          http://trac.macosforge.org/projects/launchd/changeset/23937
Author:   dsorresso at apple.com
Date:     2009-10-07 17:53:09 -0700 (Wed, 07 Oct 2009)
Log Message:
-----------
Final-looking Jetsam changes.

Modified Paths:
--------------
    branches/PR-7178164/launchd/src/launch_priv.h
    branches/PR-7178164/launchd/src/launchd_core_logic.c

Modified: branches/PR-7178164/launchd/src/launch_priv.h
===================================================================
--- branches/PR-7178164/launchd/src/launch_priv.h	2009-10-07 20:08:49 UTC (rev 23936)
+++ branches/PR-7178164/launchd/src/launch_priv.h	2009-10-08 00:53:09 UTC (rev 23937)
@@ -49,19 +49,21 @@
 #define LAUNCH_KEY_BATCHQUERY							"BatchQuery"
 #define LAUNCHD_DO_APPLE_INTERNAL_LOGGING				"__DoAppleInternalLogging__"
 
-#define LAUNCH_KEY_JETSAMLABEL							"JetsamLabel"
-#define LAUNCH_KEY_JETSAMFRONTMOST						"JetsamFrontmost"
-#define LAUNCH_KEY_JETSAMPRIORITY						"JetsamPriority"
-
 #define LAUNCH_JOBKEY_TRANSACTIONCOUNT					"TransactionCount"
 #define LAUNCH_JOBKEY_QUARANTINEDATA					"QuarantineData"
 #define LAUNCH_JOBKEY_SANDBOXPROFILE					"SandboxProfile"
 #define LAUNCH_JOBKEY_SANDBOXFLAGS						"SandboxFlags"
 #define LAUNCH_JOBKEY_SANDBOX_NAMED						"Named"
+#define LAUNCH_JOBKEY_JETSAMPROPERTIES					"JetsamProperties"
 #define LAUNCH_JOBKEY_JETSAMPRIORITY					"JetsamPriority"
 #define LAUNCH_JOBKEY_JETSAMMEMORYLIMIT					"JetsamMemoryLimit"
 #define LAUNCH_JOBKEY_SECURITYSESSIONUUID				"SecuritySessionUUID"
 
+#define LAUNCH_KEY_JETSAMLABEL							"JetsamLabel"
+#define LAUNCH_KEY_JETSAMFRONTMOST						"JetsamFrontmost"
+#define LAUNCH_KEY_JETSAMPRIORITY						LAUNCH_JOBKEY_JETSAMPRIORITY
+#define LAUNCH_KEY_JETSAMMEMORYLIMIT					LAUNCH_JOBKEY_JETSAMMEMORYLIMIT
+
 #define LAUNCH_JOBKEY_EMBEDDEDPRIVILEGEDISPENSATION		"EmbeddedPrivilegeDispensation"
 #define LAUNCH_JOBKEY_EMBEDDEDMAINTHREADPRIORITY		"EmbeddedMainThreadPriority"
 

Modified: branches/PR-7178164/launchd/src/launchd_core_logic.c
===================================================================
--- branches/PR-7178164/launchd/src/launchd_core_logic.c	2009-10-07 20:08:49 UTC (rev 23936)
+++ branches/PR-7178164/launchd/src/launchd_core_logic.c	2009-10-08 00:53:09 UTC (rev 23937)
@@ -91,8 +91,8 @@
 #else
 /* To make my life easier. */
 typedef struct jetsam_priority_entry {
-    pid_t pid;
-    uint32_t flags;
+	pid_t pid;
+	uint32_t flags;
 	int32_t hiwat_pages;
 	int32_t hiwat_reserved1;
 	int32_t hiwat_reserved2;
@@ -137,7 +137,6 @@
 #define LAUNCHD_DEFAULT_EXIT_TIMEOUT	20
 #define LAUNCHD_SIGKILL_TIMER			5
 #define LAUNCHD_CLEAN_KILL_TIMER		1
-#define LAUNCHD_JETSAM_PRIORITY_UNSET	0xdead1ee
 
 #define SHUTDOWN_LOG_DIR "/var/log/shutdown"
 
@@ -280,6 +279,8 @@
 static void seatbelt_setup_flags(launch_data_t obj, const char *key, void *context);
 #endif
 
+static void jetsam_property_setup(launch_data_t obj, const char *key, job_t j);
+
 typedef enum {
 	NETWORK_UP = 1,
 	NETWORK_DOWN,
@@ -546,7 +547,8 @@
 			clean_exit_timer_expired	:1, /* The job was clean, received SIGKILL and failed to exit after LAUNCHD_CLEAN_KILL_TIMER seconds. */
 			embedded_special_privileges	:1, /* The job runs as a non-root user on embedded but has select privileges of the root user. */
 			did_exec					:1, /* The job exec(2)ed successfully. */
-			migratory					:1; /* The (anonymous) job called vprocmgr_switch_to_session(). */
+			migratory					:1, /* The (anonymous) job called vprocmgr_switch_to_session(). */
+			jetsam_properties			:1; /* The job has Jetsam limits in place. */
 	mode_t mask;
 	pid_t tracing_pid;
 	mach_port_t audit_session;
@@ -642,10 +644,6 @@
 
 void eliminate_double_reboot(void);
 
-/* For Jetsam. */
-static int job_cmp(const job_t *lhs, const job_t *rhs);
-int launchd_set_jetsam_priorities(launch_data_t priorities);
-
 /* file local globals */
 static size_t total_children;
 static size_t total_anon_children;
@@ -1203,7 +1201,7 @@
 		/* Not a big deal if this fails. It means that the timer's already been freed. */
 		kevent_mod((uintptr_t)&j->exit_timeout, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
 	}
-	if( j->jetsam_priority != LAUNCHD_JETSAM_PRIORITY_UNSET ) {
+	if( j->jetsam_properties ) {
 		LIST_REMOVE(j, jetsam_sle);
 		j->mgr->jetsam_jobs_cnt--;
 	}
@@ -1535,7 +1533,8 @@
 	j->currently_ignored = true;
 	j->ondemand = true;
 	j->checkedin = true;
-	j->jetsam_priority = LAUNCHD_JETSAM_PRIORITY_UNSET;
+	j->jetsam_priority = -1;
+	j->jetsam_memlimit = -1;
 	uuid_clear(j->expected_audit_uuid);
 	
 	if (prog) {
@@ -1898,21 +1897,6 @@
 			j->main_thread_priority = value;
 		}
 		break;
-	case 'j':
-	case 'J':
-		if( strcasecmp(key, LAUNCH_JOBKEY_JETSAMPRIORITY) == 0 ) {
-			job_log(j, LOG_DEBUG, "Importing job with priority: %lld", value);
-			j->jetsam_priority = (typeof(j->jetsam_priority))value;
-			LIST_INSERT_HEAD(&j->mgr->jetsam_jobs, j, jetsam_sle);
-			j->mgr->jetsam_jobs_cnt++;
-		} else if( strcasecmp(key, LAUNCH_JOBKEY_JETSAMMEMORYLIMIT) == 0 ) {
-			/* The Jetsam stuff really needs to be in its own dictionary. For now,
-			 * we'll require that anyone who wants to do anything with Jetsam must
-			 * set a priority, even if they only want the memory limit stuff.
-			 */
-			j->jetsam_memlimit = (typeof(j->jetsam_memlimit))value;
-		}
-		break;
 	case 'n':
 	case 'N':
 		if (strcasecmp(key, LAUNCH_JOBKEY_NICE) == 0) {
@@ -2061,6 +2045,16 @@
 			}
 		}
 		break;
+	case 'j':
+	case 'J':
+		if( strcasecmp(key, LAUNCH_JOBKEY_JETSAMPROPERTIES) == 0 ) {
+			if( job_assumes(j, !j->jetsam_properties) ) {
+				LIST_INSERT_HEAD(&j->mgr->jetsam_jobs, j, jetsam_sle);
+				j->mgr->jetsam_jobs_cnt++;
+				j->jetsam_properties = true;
+			}
+			launch_data_dict_iterate(value, (void (*)(launch_data_t, const char *, void *))jetsam_property_setup, j);
+		}
 	case 'e':
 	case 'E':
 		if (strcasecmp(key, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES) == 0) {
@@ -4191,7 +4185,7 @@
 	}
 
 #if !TARGET_OS_EMBEDDED	
-	if( j->jetsam_priority != LAUNCHD_JETSAM_PRIORITY_UNSET ) {
+	if( j->jetsam_properties ) {
 		job_assumes(j, proc_setpcontrol(PROC_SETPC_TERMINATE) == 0);
 	}
 #endif
@@ -8923,19 +8917,25 @@
 	}
 }
 
-static int
-job_cmp(const job_t *lhs, const job_t *rhs)
+void
+jetsam_property_setup(launch_data_t obj, const char *key, job_t j)
 {
-	job_t _lhs = *lhs;
-	job_t _rhs = *rhs;
-	/* Sort in descending order. (Priority correlates to the soonishness with which you will be killed.) */
-	if( _lhs->jetsam_priority > _rhs->jetsam_priority ) {
-		return -1;
-	} else if( _lhs->jetsam_priority < _rhs->jetsam_priority ) {
-		return 1;
+	job_log(j, LOG_NOTICE, "Importing Jetsam job...");
+	if( strcasecmp(key, LAUNCH_JOBKEY_JETSAMPRIORITY) == 0 && launch_data_get_type(obj) == LAUNCH_DATA_INTEGER ) {
+		j->jetsam_priority = (typeof(j->jetsam_priority))launch_data_get_integer(obj);
+		job_log(j, LOG_NOTICE, "Priority: %d", j->jetsam_priority);
+	} else if( strcasecmp(key, LAUNCH_JOBKEY_JETSAMMEMORYLIMIT) == 0 && launch_data_get_type(obj) == LAUNCH_DATA_INTEGER ) {
+		j->jetsam_memlimit = (typeof(j->jetsam_memlimit))launch_data_get_integer(obj);
+		job_log(j, LOG_NOTICE, "Memory limit: %d", j->jetsam_memlimit);
+	} else if( strcasecmp(key, LAUNCH_KEY_JETSAMFRONTMOST) == 0 ) {
+		/* Ignore. We only recognize this key so we don't complain. You can't set this in a plist. */
+	} else if( strcasecmp(key, LAUNCH_KEY_JETSAMLABEL) == 0 ) {
+		/* Ignore. This key is present in SpringBoard's request dictionary, so we don't want to
+		 * complain about it.
+		 */
+	} else {
+		job_log(j, LOG_ERR, "Unknown Jetsam key: %s", key);
 	}
-	
-	return 0;
 }
 
 int
@@ -8981,55 +8981,60 @@
 		if( !launchd_assumes(ji != NULL) ) {
 			continue;
 		}
-		
-		launch_data_t pri;
-		typeof(ji->jetsam_priority) _pri = 0;
-		if( !launchd_assumes(pri = launch_data_dict_lookup(ldi, LAUNCH_KEY_JETSAMPRIORITY)) || launch_data_get_type(pri) != LAUNCH_DATA_INTEGER ) {
-			continue;
-		}
-		_pri = (typeof(_pri))launch_data_get_integer(pri);
-		
-		if( ji->jetsam_priority == LAUNCHD_JETSAM_PRIORITY_UNSET ) {
-			LIST_INSERT_HEAD(&ji->mgr->jetsam_jobs, ji, jetsam_sle);
-			ji->mgr->jetsam_jobs_cnt++;
-		}
-		ji->jetsam_priority = _pri;
-		
+
+		launch_data_dict_iterate(ldi, (void (*)(launch_data_t, const char *, void *))jetsam_property_setup, ji);
+
 		launch_data_t frontmost = NULL;
-		if( !(frontmost = launch_data_dict_lookup(ldi, LAUNCH_KEY_JETSAMFRONTMOST)) || launch_data_get_type(frontmost) != LAUNCH_DATA_BOOL ) {
-			ji->jetsam_frontmost = false;
-			continue;
+		if( (frontmost = launch_data_dict_lookup(ldi, LAUNCH_KEY_JETSAMFRONTMOST)) && launch_data_get_type(frontmost) == LAUNCH_DATA_BOOL ) {
+			ji->jetsam_frontmost = launch_data_get_bool(frontmost);
 		}
-		ji->jetsam_frontmost = launch_data_get_bool(frontmost);
 		
-		launch_data_t memlimit = 0;
-		if( !(memlimit = launch_data_dict_lookup(ldi, LAUNCH_JOBKEY_JETSAMMEMORYLIMIT)) || launch_data_get_type(frontmost) != LAUNCH_DATA_INTEGER ) {
-			ji->jetsam_memlimit = -1;
-			continue;
+		/* If the job wasn't in the Jetsam list before, add it. */
+		if( job_assumes(ji, ji->jetsam_priority || ji->jetsam_frontmost || ji->jetsam_memlimit) ) {
+			if( !ji->jetsam_properties ) {
+				LIST_INSERT_HEAD(&ji->mgr->jetsam_jobs, ji, jetsam_sle);
+				ji->mgr->jetsam_jobs_cnt++;
+			}
 		}
-		ji->jetsam_memlimit = (uint32_t)launch_data_get_integer(memlimit);
 	}
 	
 	i = 0;
 	job_t *jobs = (job_t *)calloc(jm->jetsam_jobs_cnt, sizeof(job_t));
-	LIST_FOREACH( ji, &jm->jetsam_jobs, jetsam_sle ) {
-		if( ji->p ) {
-			jobs[i] = ji;
-			i++;
+	if( launchd_assumes(jobs != NULL) ) {
+		LIST_FOREACH( ji, &jm->jetsam_jobs, jetsam_sle ) {
+			if( ji->p ) {
+				jobs[i] = ji;
+				i++;
+			}
 		}
 	}
+	
 	size_t totalpris = i;
 	
 	int result = EINVAL;
-	if( launchd_assumes(totalpris > 0) ) {
-		qsort((void *)jobs, totalpris, sizeof(job_t), (int (*)(const void *, const void *))job_cmp);
+	
+	/* It is conceivable that there could be no Jetsam jobs running. */
+	if( totalpris > 0 ) {
+		/* Yay blocks! */
+		qsort_b((void *)jobs, totalpris, sizeof(job_t), ^ int (const void *lhs, const void *rhs) {
+			job_t _lhs = *(job_t *)lhs;
+			job_t _rhs = *(job_t *)rhs;
+			/* Sort in descending order. (Priority correlates to the soonishness with which you will be killed.) */
+			if( _lhs->jetsam_priority > _rhs->jetsam_priority ) {
+				return -1;
+			} else if( _lhs->jetsam_priority < _rhs->jetsam_priority ) {
+				return 1;
+			}
+			
+			return 0;
+		});
 		
 		jetsam_priority_entry_t *jpris = (jetsam_priority_entry_t *)calloc(totalpris, sizeof(jetsam_priority_entry_t));
 		if( !launchd_assumes(jpris != NULL) ) {
 			result = ENOMEM;
 		} else {
 			for( i = 0; i < totalpris; i++ ) {
-				jpris[i].pid = jobs[i]->p;
+				jpris[i].pid = jobs[i]->p; /* Subject to time-of-use vs. time-of-check, obviously. */
 				jpris[i].flags |= jobs[i]->jetsam_frontmost ? kJetsamFlagsFrontmost : 0;
 				jpris[i].hiwat_pages = jobs[i]->jetsam_memlimit;
 			}
@@ -9041,7 +9046,10 @@
 			free(jpris);
 		}
 	}
-	free(jobs);
 	
+	if( jobs ) {
+		free(jobs);
+	}
+	
 	return result;
 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20091007/cf4873e7/attachment-0001.html>


More information about the launchd-changes mailing list