Example #1
0
int ooh323c_start_call_thread(ooCallData *call) {
 char c = 'c';
 struct callthread *cur = callThreads;

 ast_mutex_lock(&callThreadsLock);
 while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
	cur = cur->next;
 }
 ast_mutex_unlock(&callThreadsLock);

 if (cur != NULL) {
   if (cur->inUse || write(cur->thePipe[1], &c, 1) < 0) {
	ast_mutex_unlock(&cur->lock);
	cur = NULL;
   }
 }

/* make new thread */
 if (cur == NULL) {
	if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
		ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
							call->callToken);
		return -1;
	}

	ast_module_ref(myself);
	if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) {
		ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken);
		ast_free(cur);
		return -1;
	}
	cur->inUse = TRUE;
	cur->call = call;

	ast_mutex_init(&cur->lock);

	if (gH323Debug)
		ast_debug(1,"new call thread created for call %s\n", call->callToken);

	if(ast_pthread_create_detached_background(&call->callThread, NULL, ooh323c_call_thread, cur) < 0)
 	{
  		ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n",
					call->callToken);
		ast_mutex_destroy(&cur->lock);
		close(cur->thePipe[0]);
		close(cur->thePipe[1]);
		ast_free(cur);
  		return -1;
 	}

 } else {
	if (gH323Debug)
		ast_debug(1,"using existing call thread for call %s\n", call->callToken);
	cur->inUse = TRUE;
	cur->call = call;
	ast_mutex_unlock(&cur->lock);

 }
 return 0;
}
Example #2
0
/*! \brief Called when a frame should be written out to a channel */
static int bridge_write(struct ast_channel *ast, struct ast_frame *f)
{
	struct bridge_pvt *p = ast->tech_pvt;
	struct ast_channel *other;

	ast_mutex_lock(&p->lock);

	other = (p->input == ast ? p->output : p->input);

	while (other && ast_channel_trylock(other)) {
		ast_mutex_unlock(&p->lock);
		do {
			CHANNEL_DEADLOCK_AVOIDANCE(ast);
		} while (ast_mutex_trylock(&p->lock));
		other = (p->input == ast ? p->output : p->input);
	}

	/* We basically queue the frame up on the other channel if present */
	if (other) {
		ast_queue_frame(other, f);
		ast_channel_unlock(other);
	}

	ast_mutex_unlock(&p->lock);

	return 0;
}
Example #3
0
int usecount(void)
{
	/* Simplistic use count */
	if (ast_mutex_trylock(&tds_lock)) {
		return 1;
	} else {
		ast_mutex_unlock(&tds_lock);
		return 0;
	}
}
Example #4
0
/*! \brief Helper function to not deadlock when queueing the hangup frame */
static void bridge_queue_hangup(struct bridge_pvt *p, struct ast_channel *us)
{
	struct ast_channel *other = (p->input == us ? p->output : p->input);

	while (other && ast_channel_trylock(other)) {
		ast_mutex_unlock(&p->lock);
		do {
			CHANNEL_DEADLOCK_AVOIDANCE(us);
		} while (ast_mutex_trylock(&p->lock));
		other = (p->input == us ? p->output : p->input);
	}

	/* We basically queue the frame up on the other channel if present */
	if (other) {
		ast_queue_hangup(other);
		ast_channel_unlock(other);
	}

	return;
}