[asterisk-commits] schmidts: branch schmidts/unleash-the-beast r335786 - in /team/schmidts/unlea...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Sep 14 05:38:50 CDT 2011


Author: schmidts
Date: Wed Sep 14 05:38:48 2011
New Revision: 335786

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=335786
Log:
step 2 of backporting patches from review 1003
cps increase to step 1 90

Modified:
    team/schmidts/unleash-the-beast/loadtestresults
    team/schmidts/unleash-the-beast/main/pbx.c

Modified: team/schmidts/unleash-the-beast/loadtestresults
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/loadtestresults?view=diff&rev=335786&r1=335785&r2=335786
==============================================================================
--- team/schmidts/unleash-the-beast/loadtestresults (original)
+++ team/schmidts/unleash-the-beast/loadtestresults Wed Sep 14 05:38:48 2011
@@ -16,6 +16,11 @@
 1.8 at rev: 335779
 	50 cps
 	1221 concurrent calls
+
 Unleash-the-beast Step 1
 	270 cps
 	3042 concurrent calls	
+
+Unleash-the-beast Step 2
+	360 cps
+	3042 concurrent calls	

Modified: team/schmidts/unleash-the-beast/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/schmidts/unleash-the-beast/main/pbx.c?view=diff&rev=335786&r1=335785&r2=335786
==============================================================================
--- team/schmidts/unleash-the-beast/main/pbx.c (original)
+++ team/schmidts/unleash-the-beast/main/pbx.c Wed Sep 14 05:38:48 2011
@@ -946,12 +946,103 @@
 	char exten_name[AST_MAX_EXTENSION];/*!< Extension of destroyed hint extension. */
 };
 
+#define HINTDEVICE_DATA_LENGTH 16
+AST_THREADSTORAGE(hintdevice_data);
+
 /* --- Hash tables of various objects --------*/
 #ifdef LOW_MEMORY
 static const int HASH_EXTENHINT_SIZE = 17;
 #else
 static const int HASH_EXTENHINT_SIZE = 563;
 #endif
+
+/*! \brief Container for hint devices
+*/
+static struct ao2_container *hintdevices;
+
+/*! \brief Structure for dial plan hint devices
+
+  \note hintdevice is one device pointing to a hint.
+*/
+struct ast_hintdevice {
+
+	struct ast_hint *hint;
+	char hintdevice[1];
+};
+
+
+/*!
+ * \note Using the device for hash
+ */
+static int hintdevice_hash_cb(const void *obj, const int flags)
+{
+	const struct ast_hintdevice *ext = obj;
+
+	return ast_str_case_hash(ext->hintdevice);
+}
+/*!
+ * \note Devices on hints are not unique so no CMP_STOP is returned
+ * Dont use ao2_find against hintdevices container cause there allways
+ * could be more than one result.
+ */
+static int hintdevice_cmp_multiple(void *obj, void *arg, int flags)
+{
+	struct ast_hintdevice *ext = obj, *ext2 = arg;
+
+	return !strcasecmp(ext->hintdevice, ext2->hintdevice) ? CMP_MATCH  : 0;
+}
+
+/*
+ * \details This is used with ao2_callback to remove old devices
+ * when they are linked to the hint
+*/
+static int hintdevice_remove_cb(void *deviceobj, void *arg, int flags)
+{
+        struct ast_hintdevice *device = deviceobj;
+	struct ast_hint *hint = arg;
+
+        return (device->hint == hint) ? CMP_MATCH : 0;
+}
+
+static int remove_hintdevice(struct ast_hint *hint)
+{
+
+	/* iterate through all devices and remove the devices which are linked to this hint */
+	ao2_t_callback(hintdevices, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, hintdevice_remove_cb, hint ,
+		"callback to remove all devices which are linked to a hint");
+	return 0;
+}
+
+/*! \brief add hintdevice structure and link it into the container.
+ */
+static int add_hintdevice(struct ast_hint *hint, const char *devicelist)
+{
+	struct ast_str *str;
+	char *cur=NULL,*parse;
+	struct ast_hintdevice *device;
+	int devicelength = 0;
+
+	if (!(str = ast_str_thread_get(&hintdevice_data, 16))) {
+		return -1;
+	}
+	ast_str_set(&str, 0, "%s", devicelist);
+	parse = ast_str_buffer(str);
+
+	while ((cur = strsep(&parse, "&"))) {
+		devicelength = strlen(cur);
+		if (!(device = ao2_t_alloc(sizeof(*device) + devicelength, NULL, "allocating a hintdevice structure"))) {
+			return -1;
+		}
+		strcpy(device->hintdevice, cur);
+		device->hint = hint;
+		ao2_t_link(hintdevices, device, "Linking device into hintdevice container.");
+		ao2_t_ref(device, -1, "hintdevice is linked so we can unref");
+	}
+
+	return 0;
+}
+
+
 
 static const struct cfextension_states {
 	int extension_state;
@@ -4270,45 +4361,44 @@
 static int handle_statechange(void *datap)
 {
 	struct ast_hint *hint;
-	struct ast_str *hint_app;
+	struct ast_str *hint_app = NULL;
+	struct ast_hintdevice *device, *cmpdevice;
 	struct statechange *sc = datap;
-	struct ao2_iterator i;
+	struct ao2_iterator *i;
 	struct ao2_iterator cb_iter;
 	char context_name[AST_MAX_CONTEXT];
 	char exten_name[AST_MAX_EXTENSION];
 
-	hint_app = ast_str_create(1024);
-	if (!hint_app) {
-		ast_free(sc);
+	if (ao2_container_count(hintdevices) == 0) {
+		return 0;
+	}
+	if (!(cmpdevice = ast_malloc(sizeof(*cmpdevice) + strlen(sc->dev)))) {
 		return -1;
 	}
+	strcpy(cmpdevice->hintdevice, sc->dev);
 
 	ast_mutex_lock(&context_merge_lock);/* Hold off ast_merge_contexts_and_delete */
-	i = ao2_iterator_init(hints, 0);
-	for (; (hint = ao2_iterator_next(&i)); ao2_ref(hint, -1)) {
+	i = ao2_t_callback(hintdevices,
+		OBJ_POINTER | OBJ_MULTIPLE,
+		hintdevice_cmp_multiple,
+		cmpdevice,
+		"find devices in container");
+//	i = ao2_iterator_init(hints, 0);
+	for (; (device = ao2_iterator_next(i)); ao2_ref(device, -1)) {
 		struct ast_state_cb *state_cb;
-		char *cur, *parse;
 		int state;
-
+		if (!device->hint) {
+			continue;
+		}
+
+		ao2_lock(hints);
 		ao2_lock(hint);
+		hint = device->hint;
+
 		if (!hint->exten) {
 			/* The extension has already been destroyed */
 			ao2_unlock(hint);
-			continue;
-		}
-
-		/* Does this hint monitor the device that changed state? */
-		ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten));
-		parse = ast_str_buffer(hint_app);
-		while ((cur = strsep(&parse, "&"))) {
-			if (!strcasecmp(cur, sc->dev)) {
-				/* The hint monitors the device. */
-				break;
-			}
-		}
-		if (!cur) {
-			/* The hint does not monitor the device. */
-			ao2_unlock(hint);
+			ao2_unlock(hints);
 			continue;
 		}
 
@@ -4323,6 +4413,7 @@
 			sizeof(exten_name));
 		ast_str_set(&hint_app, 0, "%s", ast_get_extension_app(hint->exten));
 		ao2_unlock(hint);
+		ao2_unlock(hints);
 
 		/*
 		 * Get device state for this hint.
@@ -4364,11 +4455,18 @@
 		}
 		ao2_iterator_destroy(&cb_iter);
 	}
-	ao2_iterator_destroy(&i);
+	ao2_iterator_destroy(i);
 	ast_mutex_unlock(&context_merge_lock);
 
-	ast_free(hint_app);
+	if (hint_app) {
+		ast_free(hint_app);
+		hint_app = NULL;
+	}
 	ast_free(sc);
+	if (cmpdevice) {
+		ast_free(cmpdevice);
+		cmpdevice = NULL;
+	}
 	return 0;
 }
 
@@ -4538,6 +4636,7 @@
 			context_name = ast_get_context_name(ast_get_extension_context(hint->exten));
 			exten_name = ast_get_extension_name(hint->exten);
 			hint->exten = NULL;
+			remove_hintdevice(hint);
 		} else {
 			/* The extension has already been destroyed */
 			context_name = hint->context_name;
@@ -4618,6 +4717,7 @@
 
 	/* Prevent multiple add hints from adding the same hint at the same time. */
 	ao2_lock(hints);
+	ao2_lock(hintdevices);
 
 	/* Search if hint exists, do nothing */
 	hint_found = ao2_find(hints, e, 0);
@@ -4634,8 +4734,14 @@
 	ast_debug(2, "HINTS: Adding hint %s: %s\n",
 		ast_get_extension_name(e), ast_get_extension_app(e));
 	ao2_link(hints, hint_new);
+	if (add_hintdevice(hint_new, ast_get_extension_app(e))) {
+		ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
+			ast_get_extension_name(e),
+			ast_get_context_name(ast_get_extension_context(e)));
+	}
 
 	ao2_unlock(hints);
+	ao2_unlock(hintdevices);
 	ao2_ref(hint_new, -1);
 
 	return 0;
@@ -4665,6 +4771,12 @@
 	/* Update the hint and put it back in the hints container. */
 	ao2_lock(hint);
 	hint->exten = ne;
+	remove_hintdevice(hint);
+	if (add_hintdevice(hint, ast_get_extension_app(ne))) {
+		ast_log(LOG_WARNING, "Could not add devices for hint: %s@%s.\n",
+			ast_get_extension_name(ne),
+			ast_get_context_name(ast_get_extension_context(ne)));
+	}
 	ao2_unlock(hint);
 	ao2_link(hints, hint);
 
@@ -10488,6 +10600,7 @@
 int ast_pbx_init(void)
 {
 	hints = ao2_container_alloc(HASH_EXTENHINT_SIZE, hint_hash, hint_cmp);
+	hintdevices = ao2_container_alloc(HASH_EXTENHINT_SIZE, hintdevice_hash_cb, hintdevice_cmp_multiple);
 	statecbs = ao2_container_alloc(HASH_EXTENHINT_SIZE, NULL, statecbs_cmp);
 
 	return (hints && statecbs) ? 0 : -1;




More information about the asterisk-commits mailing list