SOURCES: callweaver-fixes.patch - generator fix from svn

arekm arekm at pld-linux.org
Tue Sep 25 12:53:40 CEST 2007


Author: arekm                        Date: Tue Sep 25 10:53:40 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- generator fix from svn

---- Files affected:
SOURCES:
   callweaver-fixes.patch (1.3 -> 1.4) 

---- Diffs:

================================================================
Index: SOURCES/callweaver-fixes.patch
diff -u SOURCES/callweaver-fixes.patch:1.3 SOURCES/callweaver-fixes.patch:1.4
--- SOURCES/callweaver-fixes.patch:1.3	Mon Sep 24 20:19:49 2007
+++ SOURCES/callweaver-fixes.patch	Tue Sep 25 12:53:34 2007
@@ -83,3 +83,295 @@
  /* Check it	
  	if (opbx_set_write_format(chan, OPBX_FORMAT_SLINEAR)) {
  		opbx_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name);
+
+Index: corelib/channel.c
+===================================================================
+--- corelib/channel.c	(wersja 4088)
++++ corelib/channel.c	(kopia robocza)
+@@ -1021,7 +1021,7 @@
+ 	opbx_copy_string(name, chan->name, sizeof(name));
+ 
+ 	/* Stop generator thread */
+-	opbx_generator_stop_thread(chan);
++	opbx_generator_deactivate(chan);
+ 
+ 	/* Stop monitoring */
+ 	if (chan->monitor)
+Index: corelib/generator.c
+===================================================================
+--- corelib/generator.c	(wersja 4088)
++++ corelib/generator.c	(kopia robocza)
+@@ -48,29 +48,6 @@
+  * ****************************************************************************
+  */
+ 
+-/*
+- * Stops the generator thread associated with the channel.
+- * Called when the channel is being freed by opbx_channel_free.
+- */
+-void opbx_generator_stop_thread(struct opbx_channel *pchan)
+-{
+-	opbx_mutex_lock(&pchan->gcd.lock);
+-	if (pchan->gcd.gen_req == gen_req_activate)
+-		pchan->gcd.gen_free(pchan, pchan->gcd.gen_data);
+-	if (pchan->gcd.pgenerator_thread) {
+-		pchan->gcd.gen_req = gen_req_shutdown;
+-		opbx_cond_signal(&pchan->gcd.gen_req_cond);
+-		opbx_mutex_unlock(&pchan->gcd.lock);
+-		pthread_join(*pchan->gcd.pgenerator_thread, NULL);
+-		free(pchan->gcd.pgenerator_thread);
+-		pchan->gcd.pgenerator_thread = NULL;
+-		opbx_cond_destroy(&pchan->gcd.gen_req_cond);
+-	} else {
+-		opbx_mutex_unlock(&pchan->gcd.lock);
+-	}
+-	opbx_mutex_destroy(&pchan->gcd.lock);
+-}
+-
+ /* Activate channel generator */
+ int opbx_generator_activate(struct opbx_channel *chan, struct opbx_generator *gen, void *params)
+ {
+@@ -94,11 +71,6 @@
+ 			return -1;
+ 		}
+ 
+-		/* In case the generator thread hasn't yet processed a
+-		 * previous activation request, we need to release its data */
+-		if (pgcd->gen_req == gen_req_activate)
+-			pgcd->gen_free(chan, pgcd->gen_data);
+-		
+ 		/* Setup new request */
+ 		pgcd->gen_data = gen_data;
+ 		pgcd->gen_func = gen->generate;
+@@ -110,7 +82,7 @@
+ 		pgcd->gen_free = gen->release;
+ 
+ 		/* Signal generator thread to activate new generator */
+-		pgcd->gen_req = gen_req_activate;
++		pgcd->gen_req = gen_req_null;
+ 		opbx_cond_signal(&pgcd->gen_req_cond);
+ 
+ 		/* Our job is done */
+@@ -127,24 +99,30 @@
+ void opbx_generator_deactivate(struct opbx_channel *chan)
+ {
+ 	struct opbx_generator_channel_data *pgcd = &chan->gcd;
++	void *gen_data;
++	void (*gen_free)(struct opbx_channel *chan, void *data);
+ 	pthread_t thread = OPBX_PTHREADT_NULL;
+ 
+-	opbx_log(LOG_DEBUG, "Trying to deactivate generator in %s\n", 
+-		 chan->name);
++	opbx_log(LOG_DEBUG, "Trying to deactivate generator in %s\n", chan->name);
+ 
+ 	/* In case the generator thread hasn't yet processed a
+ 	 * previous activation request, we need to release its data */
+ 	opbx_mutex_lock(&pgcd->lock);
+-	if (pgcd->gen_req == gen_req_activate)
+-		pgcd->gen_free(chan, pgcd->gen_data);
+-		
++
+ 	/* Current generator, if any, gets deactivated by signaling
+ 	 * new request with request code being req_deactivate */
+ 	pgcd->gen_req = gen_req_deactivate;
+ 
+ 	/* Only signal the condition if we actually have a thread */
++	gen_free = NULL;
++	gen_data = NULL;
+ 	if ( pgcd->pgenerator_thread ) {
+ 		thread = *pgcd->pgenerator_thread;
++		free(pgcd->pgenerator_thread);
++		pgcd->pgenerator_thread = NULL;
++		gen_free = pgcd->gen_free;
++		gen_data = pgcd->gen_data;
++		pgcd->gen_is_active = 0;
+     		opbx_cond_signal(&pgcd->gen_req_cond);
+ 	}
+ 
+@@ -152,6 +130,8 @@
+ 
+ 	if (!pthread_equal(thread, OPBX_PTHREADT_NULL)) {
+ 		pthread_join(thread, NULL);
++		if (gen_free)
++			gen_free(chan, gen_data);
+ 		opbx_log(LOG_DEBUG, "Generator on %s stopped\n", chan->name);
+ 	}
+ }
+@@ -170,11 +150,16 @@
+ 	struct opbx_generator_channel_data *pgcd = &chan->gcd;
+ 	int res;
+ 
++	opbx_mutex_lock(&pgcd->lock);
++
+ 	if (pgcd->pgenerator_thread) {
+ 		res = pthread_equal(*pgcd->pgenerator_thread, pthread_self());
+ 	} else {
+ 		res = 0;
+ 	}
++
++	opbx_mutex_unlock(&pgcd->lock);
++
+ 	return res;
+ }
+ 
+@@ -200,106 +185,59 @@
+ 	long sleep_interval_ns;
+ 	int res;
+ 
++	opbx_log(LOG_DEBUG, "Generator thread started on %s\n", chan->name);
+ 
+ 	/* Loop continuously until shutdown request is received */
+ 	opbx_mutex_lock(&pgcd->lock);
+-	opbx_log(LOG_DEBUG, "Generator thread started on %s\n",
+-		 chan->name);
+-	cur_gen_data = NULL;
+-	cur_gen_samp = 0;
+-	cur_gen_func = NULL;
+-	cur_gen_free = NULL;
+-	sleep_interval_ns = 0;
+-	for (;;) {
+-		/* If generator is active, wait for new request
+-		 * or generate after timeout. If generator is not
+-		 * active, just wait for new request. */
+-		if (pgcd->gen_is_active) {
+-			for (;;) {
+-				/* Sleep based on number of samples */
+-				ts.tv_nsec += sleep_interval_ns;
+-				if (ts.tv_nsec >= 1000000000L) {
+-					++ts.tv_sec;
+-					ts.tv_nsec -= 1000000000L;
+-				}
+-				res = opbx_cond_timedwait(&pgcd->gen_req_cond, &pgcd->lock, &ts);
+-				if (pgcd->gen_req) {
+-					/* Got new request */
+-					break;
+-				} else if (res == ETIMEDOUT) {
+-			 		/* We've got some generating to do. */
+ 
+-					/* Need to unlock generator lock prior
+-					 * to calling generate callback because
+-					 * it will try to acquire channel lock
+-					 * at least by opbx_write. This mean we
+-					 * can receive new request here */
+-					opbx_mutex_unlock(&pgcd->lock);
+-					res = cur_gen_func(chan, cur_gen_data, cur_gen_samp);
+-					opbx_mutex_lock(&pgcd->lock);
+-					if (res || pgcd->gen_req) {
+-						/* Got generator error or new
+-						 * request. Deactivate current
+-						 * generator */
+-						if (!pgcd->gen_req) {
+-							opbx_log(LOG_DEBUG, "Generator self-deactivating\n");
+-							pgcd->gen_req = gen_req_deactivate;
+-						}
+-						break;
+-					}
+-				}
+-			}
+-		} else {
+-			/* Just wait for new request */
+-			while (!pgcd->gen_req)
+-				opbx_cond_wait(&pgcd->gen_req_cond, &pgcd->lock);
++	/* Copy gen_* stuff to cur_gen_* stuff, set flag
++	 * gen_is_active, calculate sleep interval and
++	 * obtain current time using CLOCK_MONOTONIC. */
++	cur_gen_data = pgcd->gen_data;
++	cur_gen_samp = pgcd->gen_samp;
++	cur_gen_func = pgcd->gen_func;
++	cur_gen_free = pgcd->gen_free;
++	pgcd->gen_is_active = -1;
++	sleep_interval_ns = 1000000L * cur_gen_samp / ( pgcd->samples_per_second / 1000 );        // THIS IS BECAUSE It's HARDCODED TO 8000 samples per second. We should use the samples per second in the channel struct.
++	gettimeofday(&tv, NULL);
++	ts.tv_sec = tv.tv_sec;
++	ts.tv_nsec = 1000 * tv.tv_usec;
++
++	for (;;) {
++		/* Sleep based on number of samples */
++		ts.tv_nsec += sleep_interval_ns;
++		if (ts.tv_nsec >= 1000000000L) {
++			++ts.tv_sec;
++			ts.tv_nsec -= 1000000000L;
+ 		}
++		res = opbx_cond_timedwait(&pgcd->gen_req_cond, &pgcd->lock, &ts);
++		if (pgcd->gen_req) {
++			/* Got new request */
++			break;
++		} else if (res == ETIMEDOUT) {
++	 		/* We've got some generating to do. */
+ 
+-		/* If there is an activated generator, free its
+-		 * resources because its existence is over. */
+-		if (pgcd->gen_is_active) {
++			/* Need to unlock generator lock prior
++			 * to calling generate callback because
++			 * it will try to acquire channel lock
++			 * at least by opbx_write. This mean we
++			 * can receive new request here */
+ 			opbx_mutex_unlock(&pgcd->lock);
+-			cur_gen_free(chan, cur_gen_data);
++			res = cur_gen_func(chan, cur_gen_data, cur_gen_samp);
+ 			opbx_mutex_lock(&pgcd->lock);
+-			pgcd->gen_is_active = 0;
++			if (res || pgcd->gen_req) {
++				/* Got generator error or new
++				 * request. Deactivate current
++				 * generator */
++				if (!pgcd->gen_req)
++					opbx_log(LOG_DEBUG, "Generator self-deactivating\n");
++				break;
++			}
+ 		}
+-
+-		/* Process new request */
+-		if (pgcd->gen_req == gen_req_activate) {
+-			/* Activation request for a new generator. */
+-
+-			/* Copy gen_* stuff to cur_gen_* stuff, set flag
+-			 * gen_is_active, calculate sleep interval and
+-			 * obtain current time using CLOCK_MONOTONIC. */
+-			cur_gen_data = pgcd->gen_data;
+-			cur_gen_samp = pgcd->gen_samp;
+-			cur_gen_func = pgcd->gen_func;
+-			cur_gen_free = pgcd->gen_free;
+-			pgcd->gen_is_active = -1;
+-			sleep_interval_ns = 1000000L * cur_gen_samp / ( pgcd->samples_per_second / 1000 );        // THIS IS BECAUSE It's HARDCODED TO 8000 samples per second. We should use the samples per second in the channel struct.
+-			gettimeofday(&tv, NULL);
+-			ts.tv_sec = tv.tv_sec;
+-			ts.tv_nsec = 1000 * tv.tv_usec;
+-		} else if (pgcd->gen_req == gen_req_shutdown) {
+-			/* Shutdown requests. */
+-			/* Just break the loop */
+-			break;
+-		} else if (pgcd->gen_req == gen_req_deactivate) {
+-			/* Shutdown requests. */
+-			/* Just break the loop */
+-			break;
+-		} else if (pgcd->gen_req != gen_req_deactivate) {
+-			opbx_log(LOG_DEBUG, "Unexpected generator request (%d).\n", pgcd->gen_req);
+-		}
+-
+-		/* Reset request */
+-		pgcd->gen_req = gen_req_null;
+ 	}
+ 
+ 	/* Got request to shutdown. */
+ 	opbx_log(LOG_DEBUG, "Generator thread shut down on %s\n", chan->name);
+-	free(pgcd->pgenerator_thread);
+-	pgcd->pgenerator_thread = NULL;
+ 	opbx_cond_destroy(&pgcd->gen_req_cond);
+ 	opbx_mutex_unlock(&pgcd->lock);
+ 	return NULL;
+Index: include/callweaver/generator.h
+===================================================================
+--- include/callweaver/generator.h	(wersja 4088)
++++ include/callweaver/generator.h	(kopia robocza)
+@@ -84,9 +84,6 @@
+ 	void (*gen_free)(struct opbx_channel *chan, void *gen_data);
+ };
+ 
+-/*! Stop channel generator thread */
+-void opbx_generator_stop_thread(struct opbx_channel *pchan);
+-
+ /*! Activate a given generator */
+ int opbx_generator_activate(struct opbx_channel *chan, struct opbx_generator *gen, void *params);
+ 
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/SOURCES/callweaver-fixes.patch?r1=1.3&r2=1.4&f=u



More information about the pld-cvs-commit mailing list