static int config_load(void) { struct cw_config *cfg; char *cat; struct osp_provider *osp, *prev = NULL, *next; cw_mutex_lock(&osplock); osp = providers; while(osp) { osp->dead = 1; osp = osp->next; } cw_mutex_unlock(&osplock); cfg = cw_config_load("osp.conf"); if (cfg) { if (!initialized) { cat = cw_variable_retrieve(cfg, "general", "accelerate"); if (cat && cw_true(cat)) if (OSPPInit(1)) { cw_log(LOG_WARNING, "Failed to enable hardware accelleration, falling back to software mode\n"); OSPPInit(0); } else hardware = 1; else OSPPInit(0); initialized = 1; } cat = cw_variable_retrieve(cfg, "general", "tokenformat"); if (cat) { if ((sscanf(cat, "%d", &tokenformat) != 1) || (tokenformat < TOKEN_ALGO_SIGNED) || (tokenformat > TOKEN_ALGO_BOTH)) { tokenformat = TOKEN_ALGO_SIGNED; cw_log(LOG_WARNING, "tokenformat should be an integer from 0 to 2, not '%s'\n", cat); } } cat = cw_category_browse(cfg, NULL); while(cat) { if (strcasecmp(cat, "general")) osp_build(cfg, cat); cat = cw_category_browse(cfg, cat); } cw_config_destroy(cfg); } else cw_log(LOG_NOTICE, "No OSP configuration found. OSP support disabled\n"); cw_mutex_lock(&osplock); osp = providers; while(osp) { next = osp->next; if (osp->dead) { if (prev) prev->next = next; else providers = next; /* XXX Cleanup OSP structure first XXX */ free(osp); } else prev = osp; osp = next; } cw_mutex_unlock(&osplock); return 0; }
/* locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone */ struct tone_zone_sound *cw_get_indication_tone(const struct tone_zone *zone, const char *indication) { struct tone_zone_sound *ts; /* we need some tonezone, pick the first */ if (zone == NULL && current_tonezone) zone = current_tonezone; /* default country? */ if (zone == NULL && tone_zones) zone = tone_zones; /* any country? */ if (zone == NULL) return 0; /* not a single country insight */ if (cw_mutex_lock(&tzlock)) { cw_log(LOG_WARNING, "Unable to lock tone_zones list\n"); return 0; } for (ts = zone->tones; ts; ts = ts->next) { if (strcasecmp(indication, ts->name) == 0) { /* found indication! */ cw_mutex_unlock(&tzlock); return ts; } } /* nothing found, sorry */ cw_mutex_unlock(&tzlock); return 0; }
static struct cw_filestream *g726_16_rewrite(FILE *f, const char *comment) { /* We don't have any header to read or anything really, but if we did, it would go here. We also might want to check and be sure it's a valid file. */ struct cw_filestream *tmp; if ((tmp = malloc(sizeof(struct cw_filestream)))) { memset(tmp, 0, sizeof(struct cw_filestream)); if (cw_mutex_lock(&g726_lock)) { cw_log(LOG_WARNING, "Unable to lock g726 list.\n"); free(tmp); return NULL; } tmp->f = f; tmp->rate = RATE_16; glistcnt++; if (option_debug) cw_log(LOG_DEBUG, "Created filestream G.726-%dk.\n", 40 - tmp->rate * 8); cw_mutex_unlock(&g726_lock); cw_update_use_count(); } else cw_log(LOG_WARNING, "Out of memory\n"); return tmp; }
static struct cw_filestream *g726_16_open(FILE *f) { /* We don't have any header to read or anything really, but if we did, it would go here. We also might want to check and be sure it's a valid file. */ struct cw_filestream *tmp; if ((tmp = malloc(sizeof(struct cw_filestream)))) { memset(tmp, 0, sizeof(struct cw_filestream)); if (cw_mutex_lock(&g726_lock)) { cw_log(LOG_WARNING, "Unable to lock g726 list.\n"); free(tmp); return NULL; } tmp->f = f; cw_fr_init_ex(&tmp->fr, CW_FRAME_VOICE, CW_FORMAT_G726, name16); tmp->rate = RATE_16; tmp->fr.data = tmp->g726; /* datalen will vary for each frame */ glistcnt++; if (option_debug) cw_log(LOG_DEBUG, "Created filestream G.726-%dk.\n", 40 - tmp->rate * 8); cw_mutex_unlock(&g726_lock); cw_update_use_count(); } return tmp; }
static struct cw_filestream *au_rewrite(FILE *f, const char *comment) { struct cw_filestream *tmp; if ((tmp = malloc(sizeof(struct cw_filestream))) == NULL) { cw_log(LOG_ERROR, "Out of memory\n"); return NULL; } memset(tmp, 0, sizeof(struct cw_filestream)); if (write_header(f)) { free(tmp); return NULL; } if (cw_mutex_lock(&au_lock)) { cw_log(LOG_WARNING, "Unable to lock au count\n"); free(tmp); return NULL; } tmp->f = f; localusecnt++; cw_mutex_unlock(&au_lock); cw_update_use_count(); return tmp; }
static int show_osp(int fd, int argc, char *argv[]) { struct osp_provider *osp; char *search = NULL; int x; int found = 0; char *tokenalgo; if ((argc < 2) || (argc > 3)) return RESULT_SHOWUSAGE; if (argc > 2) search = argv[2]; if (!search) { switch (tokenformat) { case TOKEN_ALGO_BOTH: tokenalgo = "Both"; break; case TOKEN_ALGO_UNSIGNED: tokenalgo = "Unsigned"; break; case TOKEN_ALGO_SIGNED: default: tokenalgo = "Signed"; break; } cw_cli(fd, "OSP: %s %s %s\n", initialized ? "Initialized" : "Uninitialized", hardware ? "Accelerated" : "Normal", tokenalgo); } cw_mutex_lock(&osplock); osp = providers; while(osp) { if (!search || !strcasecmp(osp->name, search)) { if (found) cw_cli(fd, "\n"); cw_cli(fd, " == OSP Provider '%s' ==\n", osp->name); cw_cli(fd, "Local Private Key: %s\n", osp->localpvtkey); cw_cli(fd, "Local Certificate: %s\n", osp->localcert); for (x=0;x<osp->cacount;x++) cw_cli(fd, "CA Certificate %d: %s\n", x + 1, osp->cacerts[x]); for (x=0;x<osp->spcount;x++) cw_cli(fd, "Service Point %d: %s\n", x + 1, osp->servicepoints[x]); cw_cli(fd, "Max Connections: %d\n", osp->maxconnections); cw_cli(fd, "Retry Delay: %d seconds\n", osp->retrydelay); cw_cli(fd, "Retry Limit: %d\n", osp->retrylimit); cw_cli(fd, "Timeout: %d milliseconds\n", osp->timeout); cw_cli(fd, "Source: %s\n", strlen(osp->source) ? osp->source : "<unspecified>"); cw_cli(fd, "OSP Handle: %d\n", osp->handle); found++; } osp = osp->next; } cw_mutex_unlock(&osplock); if (!found) { if (search) cw_cli(fd, "Unable to find OSP provider '%s'\n", search); else cw_cli(fd, "No OSP providers configured\n"); } return RESULT_SUCCESS; }
static struct cw_filestream *au_open(FILE *f) { struct cw_filestream *tmp; if (!(tmp = malloc(sizeof(struct cw_filestream)))) { cw_log(LOG_ERROR, "Out of memory\n"); return NULL; } memset(tmp, 0, sizeof(struct cw_filestream)); if (check_header(f) < 0) { free(tmp); return NULL; } if (cw_mutex_lock(&au_lock)) { cw_log(LOG_WARNING, "Unable to lock au count\n"); free(tmp); return NULL; } tmp->f = f; cw_fr_init_ex(&tmp->fr, CW_FRAME_VOICE, CW_FORMAT_ULAW, NULL); tmp->fr.data = tmp->buf; /* datalen will vary for each frame */ tmp->fr.src = name; localusecnt++; cw_mutex_unlock(&au_lock); cw_update_use_count(); return tmp; }
static void *database_queue_thread_main(void *data) { cw_mutex_lock(&db_condition_lock); for ( ;; ) { if ( db_list_head ) { //cw_log(LOG_ERROR,"DB DO SAVE OUR LIST\n"); database_flush_cache(); sleep( CACHE_COMMIT_INTERVAL ); } else { cw_cond_wait(&db_condition_save, &db_condition_lock); /* //cw_log(LOG_ERROR,"DB SAVE CONDITION RECEIVED\n"); db_list_t *e = db_list_head; cw_log(LOG_ERROR,"QUEUE NOW IS:\n"); while ( e ) { if ( e->sql ) cw_log(LOG_ERROR,"ITEM: %s\n",e->sql); e = e->next; } */ } } cw_mutex_unlock(&db_condition_lock); return NULL; }
static struct cw_filestream *pcm_rewrite(FILE *f, const char *comment) { /* We don't have any header to read or anything really, but if we did, it would go here. We also might want to check and be sure it's a valid file. */ struct cw_filestream *tmp; if ((tmp = malloc(sizeof(struct cw_filestream)))) { memset(tmp, 0, sizeof(struct cw_filestream)); if (cw_mutex_lock(&pcm_lock)) { cw_log(LOG_WARNING, "Unable to lock pcm list\n"); free(tmp); return NULL; } tmp->f = f; glistcnt++; cw_mutex_unlock(&pcm_lock); cw_update_use_count(); } else { cw_log(LOG_WARNING, "Out of memory\n"); } return tmp; }
static struct cw_filestream *pcm_open(FILE *f) { /* We don't have any header to read or anything really, but if we did, it would go here. We also might want to check and be sure it's a valid file. */ struct cw_filestream *tmp; if ((tmp = malloc(sizeof(struct cw_filestream)))) { memset(tmp, 0, sizeof(struct cw_filestream)); if (cw_mutex_lock(&pcm_lock)) { cw_log(LOG_WARNING, "Unable to lock pcm list\n"); free(tmp); return NULL; } tmp->f = f; cw_fr_init_ex(&tmp->fr, CW_FRAME_VOICE, CW_FORMAT_ULAW, name); tmp->fr.data = tmp->buf; /* datalen will vary for each frame */ glistcnt++; cw_mutex_unlock(&pcm_lock); cw_update_use_count(); } return tmp; }
static void *service_thread(void *data) { struct sched_context *con = data; cw_mutex_lock(&con->lock); pthread_cleanup_push((void (*)(void *))cw_mutex_unlock, &con->lock); for (;;) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); if (con->schedq) { struct timespec tick; tick.tv_sec = con->schedq->when.tv_sec; tick.tv_nsec = 1000 * con->schedq->when.tv_usec; while (cw_cond_timedwait(&con->service, &con->lock, &tick) < 0 && errno == EINTR); } else { while (cw_cond_wait(&con->service, &con->lock) < 0 && errno == EINTR); } pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); cw_sched_runq(con); } pthread_cleanup_pop(1); return NULL; }
int cw_sched_add_variable(struct sched_context *con, int when, cw_sched_cb callback, void *data, int variable) { /* * Schedule callback(data) to happen when ms into the future */ struct sched *tmp; int res = -1; #ifdef DEBUG_SCHED DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_add_variable()\n")); #endif cw_mutex_lock(&con->lock); if ((tmp = sched_alloc(con))) { if ((tmp->id = con->eventcnt++) < 0) tmp->id = con->eventcnt = 0; tmp->callback = callback; tmp->data = data; tmp->resched = when; tmp->variable = variable; tmp->when = cw_tvadd(cw_tvnow(), cw_samp2tv(when, 1000)); schedule(con, tmp); res = tmp->id; } #ifdef DUMP_SCHEDULER /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */ cw_sched_dump(con); #endif cw_mutex_unlock(&con->lock); return res; }
/*! * \brief Close a OGG/Vorbis filestream. * \param s A OGG/Vorbis filestream. */ static void ogg_vorbis_close(struct cw_filestream *s) { if (cw_mutex_lock(&ogg_vorbis_lock)) { cw_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n"); return; } glistcnt--; cw_mutex_unlock(&ogg_vorbis_lock); cw_update_use_count(); if (s->writing) { /* Tell the Vorbis encoder that the stream is finished * and write out the rest of the data */ vorbis_analysis_wrote(&s->vd, 0); write_stream(s); } ogg_stream_clear(&s->os); vorbis_block_clear(&s->vb); vorbis_dsp_clear(&s->vd); vorbis_comment_clear(&s->vc); vorbis_info_clear(&s->vi); if (s->writing) { ogg_sync_clear(&s->oy); } fclose(s->fp); free(s); }
static struct cw_filestream *h263_open(FILE *f) { /* We don't have any header to read or anything really, but if we did, it would go here. We also might want to check and be sure it's a valid file. */ struct cw_filestream *tmp; unsigned int ts; int res; if ((res = fread(&ts, 1, sizeof(ts), f)) < sizeof(ts)) { cw_log(LOG_WARNING, "Empty file!\n"); return NULL; } if ((tmp = malloc(sizeof(struct cw_filestream)))) { memset(tmp, 0, sizeof(struct cw_filestream)); if (cw_mutex_lock(&h263_lock)) { cw_log(LOG_WARNING, "Unable to lock h263 list\n"); free(tmp); return NULL; } tmp->f = f; cw_fr_init_ex(&tmp->fr, CW_FRAME_VIDEO, CW_FORMAT_H263, name); tmp->fr.data = tmp->h263; /* datalen will vary for each frame */ glistcnt++; cw_mutex_unlock(&h263_lock); cw_update_use_count(); } return tmp; }
int cw_autoservice_stop(struct cw_channel *chan) { int res = -1; struct asent *as, *prev; cw_mutex_lock(&autolock); as = aslist; prev = NULL; while(as) { if (as->chan == chan) break; prev = as; as = as->next; } if (as) { if (prev) prev->next = as->next; else aslist = as->next; free(as); if (!chan->_softhangup) res = 0; } if (asthread != CW_PTHREADT_NULL) pthread_kill(asthread, SIGURG); cw_mutex_unlock(&autolock); /* Wait for it to un-block */ while(cw_test_flag(chan, CW_FLAG_BLOCKING)) usleep(1000); return res; }
static int sccp_pbx_write(struct cw_channel *ast, struct cw_frame *frame) { sccp_channel_t * c = CS_CW_CHANNEL_PVT(ast); if (!c) return 0; int res = 0; if (frame->frametype != CW_FRAME_VOICE) { if (frame->frametype == CW_FRAME_IMAGE) return 0; else { cw_log(LOG_WARNING, "%s: Can't send %d type frames with SCCP write on channel %d\n", DEV_ID_LOG(c->device), frame->frametype, (c) ? c->callid : 0); return 0; } } else { if (!(frame->subclass & ast->nativeformats)) { cw_log(LOG_WARNING, "%s: Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", DEV_ID_LOG(c->device), frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); return -1; } } if (c) { cw_mutex_lock(&c->lock); if (c->rtp) { res = cw_rtp_write(c->rtp, frame); } cw_mutex_unlock(&c->lock); } return res; }
int cw_autoservice_start(struct cw_channel *chan) { int res = -1; struct asent *as; int needstart; cw_mutex_lock(&autolock); needstart = (asthread == CW_PTHREADT_NULL) ? 1 : 0 /* aslist ? 0 : 1 */; as = aslist; while(as) { if (as->chan == chan) break; as = as->next; } if (!as) { as = malloc(sizeof(struct asent)); if (as) { memset(as, 0, sizeof(struct asent)); as->chan = chan; as->next = aslist; aslist = as; res = 0; if (needstart) { if (cw_pthread_create(&asthread, NULL, autoservice_run, NULL)) { cw_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); free(aslist); aslist = NULL; res = -1; } else pthread_kill(asthread, SIGURG); } } } cw_mutex_unlock(&autolock); return res; }
void sched_context_destroy(struct sched_context *con) { struct sched *s, *sl; if (!pthread_equal(con->tid, CW_PTHREADT_NULL)) { pthread_cancel(con->tid); pthread_join(con->tid, NULL); cw_cond_destroy(&con->service); } cw_mutex_lock(&con->lock); #ifdef SCHED_MAX_CACHE /* Eliminate the cache */ s = con->schedc; while(s) { sl = s; s = s->next; free(sl); } #endif /* And the queue */ s = con->schedq; while(s) { sl = s; s = s->next; free(sl); } /* And the context */ cw_mutex_unlock(&con->lock); cw_mutex_destroy(&con->lock); free(con); }
int conference_stop_sounds( struct cw_conf_member *member ) { struct cw_conf_soundq *sound; struct cw_conf_soundq *next; if( member == NULL ) { cw_log(LOG_WARNING, "Member is null. Cannot play\n"); return 0; } // clear all sounds cw_mutex_lock(&member->lock); sound = member->soundq; member->soundq = NULL; while(sound) { next = sound->next; free(sound); sound = next; } cw_mutex_unlock(&member->lock); cw_log(CW_CONF_DEBUG,"Stopped sounds to member %s\n", member->chan->name); return 0 ; }
static void crypto_load(int ifd, int ofd) { struct cw_key *key, *nkey, *last; DIR *dir = NULL; struct dirent *ent; int note = 0; /* Mark all keys for deletion */ cw_mutex_lock(&keylock); key = keys; while(key) { key->delme = 1; key = key->next; } cw_mutex_unlock(&keylock); /* Load new keys */ dir = opendir((char *)cw_config_CW_KEY_DIR); if (dir) { while((ent = readdir(dir))) { try_load_key((char *)cw_config_CW_KEY_DIR, ent->d_name, ifd, ofd, ¬e); } closedir(dir); } else cw_log(LOG_WARNING, "Unable to open key directory '%s'\n", (char *)cw_config_CW_KEY_DIR); if (note) { cw_log(LOG_NOTICE, "Please run the command 'init keys' to enter the passcodes for the keys\n"); } cw_mutex_lock(&keylock); key = keys; last = NULL; while(key) { nkey = key->next; if (key->delme) { cw_log(LOG_DEBUG, "Deleting key %s type %d\n", key->name, key->ktype); /* Do the delete */ if (last) last->next = nkey; else keys = nkey; if (key->rsa) RSA_free(key->rsa); free(key); } else last = key; key = nkey; } cw_mutex_unlock(&keylock); }
static int sccp_pbx_indicate(struct cw_channel *ast, int ind) { sccp_channel_t * c = CS_CW_CHANNEL_PVT(ast); int res = 0; if (!c) return -1; cw_mutex_lock(&c->lock); sccp_log(10)(VERBOSE_PREFIX_3 "%s: CallWeaver indicate '%d' (%s) condition on channel %s\n", DEV_ID_LOG(c->device), ind, sccp_control2str(ind), ast->name); if (c->state == SCCP_CHANNELSTATE_CONNECTED) { /* let's callweaver emulate it */ cw_mutex_unlock(&c->lock); return -1; } /* when the rtp media stream is open we will let callweaver emulate the tones */ if (c->rtp) res = -1; switch(ind) { case CW_CONTROL_RINGING: sccp_indicate_nolock(c, SCCP_CHANNELSTATE_RINGOUT); break; case CW_CONTROL_BUSY: sccp_indicate_nolock(c, SCCP_CHANNELSTATE_BUSY); break; case CW_CONTROL_CONGESTION: sccp_indicate_nolock(c, SCCP_CHANNELSTATE_CONGESTION); break; case CW_CONTROL_PROGRESS: case CW_CONTROL_PROCEEDING: sccp_indicate_nolock(c, SCCP_CHANNELSTATE_PROCEED); res = 0; break; /* when the bridged channel hold/unhold the call we are notified here */ case CW_CONTROL_HOLD: res = 0; break; case CW_CONTROL_UNHOLD: res = 0; break; case -1: break; default: cw_log(LOG_WARNING, "SCCP: Don't know how to indicate condition %d\n", ind); res = -1; } cw_mutex_unlock(&c->lock); return res; }
int cw_osp_validate(char *provider, char *token, int *handle, unsigned int *timelimit, char *callerid, struct in_addr addr, char *extension) { char tmp[256]="", *l, *n; char iabuf[INET_ADDRSTRLEN]; char source[OSP_MAX] = ""; /* Same length as osp->source */ char *token2; int tokenlen; struct osp_provider *osp; int res = 0; unsigned int authorised, dummy; if (!provider || !strlen(provider)) provider = "default"; token2 = cw_strdupa(token); tokenlen = cw_base64decode(token2, token, strlen(token)); *handle = -1; if (!callerid) callerid = ""; cw_copy_string(tmp, callerid, sizeof(tmp)); cw_callerid_parse(tmp, &n, &l); if (!l) l = ""; else { cw_shrink_phone_number(l); if (!cw_isphonenumber(l)) l = ""; } callerid = l; cw_mutex_lock(&osplock); cw_inet_ntoa(iabuf, sizeof(iabuf), addr); osp = providers; while(osp) { if (!strcasecmp(osp->name, provider)) { if (OSPPTransactionNew(osp->handle, handle)) { cw_log(LOG_WARNING, "Unable to create OSP Transaction handle!\n"); } else { cw_copy_string(source, osp->source, sizeof(source)); res = 1; } break; } osp = osp->next; } cw_mutex_unlock(&osplock); if (res) { res = 0; dummy = 0; if (!OSPPTransactionValidateAuthorisation(*handle, iabuf, source, NULL, NULL, callerid, OSPC_E164, extension, OSPC_E164, 0, "", tokenlen, token2, &authorised, timelimit, &dummy, NULL, tokenformat)) { if (authorised) { cw_log(LOG_DEBUG, "Validated token for '%s' from '%s@%s'\n", extension, callerid, iabuf); res = 1; } } } return res; }
static struct cw_frame * sccp_pbx_read(struct cw_channel *ast) { sccp_channel_t * c = CS_CW_CHANNEL_PVT(ast); if (!c) return NULL; struct cw_frame *fr; cw_mutex_lock(&c->lock); fr = sccp_rtp_read(c); cw_mutex_unlock(&c->lock); return fr; }
void sccp_pbx_senddigit(sccp_channel_t * c, char digit) { struct cw_frame f = { CW_FRAME_DTMF, }; f.src = "SCCP"; f.subclass = digit; cw_mutex_lock(&c->lock); cw_queue_frame(c->owner, &f); cw_mutex_unlock(&c->lock); }
int cw_slinfactory_feed(struct cw_slinfactory *sf, struct cw_frame *f) { struct cw_frame *frame; if (f == NULL) return 0; cw_mutex_lock(&(sf->lock)); if (f->subclass != CW_FORMAT_SLINEAR) { if (sf->trans && f->subclass != sf->format) { cw_translator_free_path(sf->trans); sf->trans = NULL; } if (sf->trans == NULL) { if ((sf->trans = cw_translator_build_path(CW_FORMAT_SLINEAR, 8000, f->subclass, 8000)) == NULL) { cw_log(LOG_WARNING, "Cannot build a path from %s to slin\n", cw_getformatname(f->subclass)); cw_mutex_unlock(&(sf->lock)); return 0; } sf->format = f->subclass; } } if (sf->trans) { if ((frame = cw_translate(sf->trans, f, 0))) frame = cw_frdup(frame); } else { frame = cw_frdup(f); } if (frame) { int x = ++sf->queue.count; frame->next = NULL; if (sf->queue.tail) sf->queue.tail->next = frame; else sf->queue.head = frame; sf->queue.tail = frame; frame->next = NULL; sf->size += frame->datalen; cw_mutex_unlock(&(sf->lock)); return x; } cw_mutex_unlock(&(sf->lock)); return 0; }
int cw_sched_runq(struct sched_context *con) { /* * Launch all events which need to be run at this time. */ struct sched *runq, **endq, *current; struct timeval tv; int x=0; int res; #ifdef DEBUG_SCHED DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_runq()\n")); #endif cw_mutex_lock(&con->lock); /* schedule all events which are going to expire within 1ms. * We only care about millisecond accuracy anyway, so this will * help us get more than one event at one time if they are very * close together. */ tv = cw_tvadd(cw_tvnow(), cw_tv(0, 1000)); runq = con->schedq; endq = &runq; while (con->schedq && SOONER(con->schedq->when, tv)) { endq = &con->schedq->next; con->schedq = con->schedq->next; con->schedcnt--; } *endq = NULL; cw_mutex_unlock(&con->lock); while ((current = runq)) { runq = runq->next; x++; res = current->callback(current->data); if (res) { /* * If they return non-zero, we should schedule them to be * run again. */ current->when = cw_tvadd(current->when, cw_samp2tv((current->variable ? res : current->resched), 1000)); schedule(con, current); } else { /* No longer needed, so release it */ sched_release(con, current); } } return x; }
int unload_module(void) { int res; cw_mutex_lock(&localuser_lock); if ((res = cw_unregister_translator(&lintog722)) == 0) res = cw_unregister_translator(&g722tolin); if (localusecnt) res = -1; cw_mutex_unlock(&localuser_lock); return res; }
static void au_close(struct cw_filestream *s) { if (cw_mutex_lock(&au_lock)) { cw_log(LOG_WARNING, "Unable to lock au count\n"); return; } localusecnt--; cw_mutex_unlock(&au_lock); cw_update_use_count(); fclose(s->f); free(s); }
static void gsm_close(struct cw_filestream *s) { if (cw_mutex_lock(&gsm_lock)) { cw_log(LOG_WARNING, "Unable to lock gsm list\n"); return; } glistcnt--; cw_mutex_unlock(&gsm_lock); cw_update_use_count(); fclose(s->f); free(s); }
struct cw_conference* start_conference( struct cw_conf_member* member ) { struct cw_conference* conf = NULL ; // check input if ( member == NULL ) { cw_log( LOG_WARNING, "unable to handle null member\n" ) ; return NULL ; } // look for an existing conference cw_log( CW_CONF_DEBUG, "attempting to find requested conference\n" ) ; // acquire mutex cw_mutex_lock( &start_stop_conf_lock ) ; conf = find_conf( member->id ) ; // unable to find an existing conference, try to create one if ( conf == NULL ) { // create a new conference cw_log( CW_CONF_DEBUG, "attempting to create requested conference\n" ) ; // create the new conference with one member conf = create_conf( member->id, member ) ; // return an error if create_conf() failed if ( conf == NULL ) { cw_log( LOG_ERROR, "unable to find or create requested conference\n" ) ; cw_mutex_unlock( &start_stop_conf_lock ) ; return NULL ; } } else { // existing conference found, add new member to the conference // once we call add_member(), this thread // is responsible for calling delete_member() // add_member( conf, member) ; } // release mutex cw_mutex_unlock( &start_stop_conf_lock ) ; return conf ; }