Wed Jan 8 2020 09:49:58

Asterisk developer's documentation


bridge_multiplexed.c File Reference

Two channel bridging module which groups bridges into batches of threads. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/bridging.h"
#include "asterisk/bridging_technology.h"
#include "asterisk/frame.h"
#include "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  multiplexed_thread
 Structure which represents a single thread handling multiple 2 channel bridges. More...
 

Macros

#define MULTIPLEXED_BUCKETS   53
 Number of buckets our multiplexed thread container can have. More...
 
#define MULTIPLEXED_MAX_CHANNELS   8
 Number of channels we handle in a single thread. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void destroy_multiplexed_thread (void *obj)
 Destroy callback for a multiplexed thread structure. More...
 
static int find_multiplexed_thread (void *obj, void *arg, int flags)
 Callback function for finding a free multiplexed thread. More...
 
static int load_module (void)
 
static void multiplexed_add_or_remove (struct multiplexed_thread *multiplexed_thread, struct ast_channel *chan, int add)
 Helper function which adds or removes a channel and nudges the thread. More...
 
static int multiplexed_bridge_create (struct ast_bridge *bridge)
 Create function which finds/reserves/references a multiplexed thread structure. More...
 
static int multiplexed_bridge_destroy (struct ast_bridge *bridge)
 Destroy function which unreserves/unreferences/removes a multiplexed thread structure. More...
 
static int multiplexed_bridge_join (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 Join function which actually adds the channel into the array to be monitored. More...
 
static int multiplexed_bridge_leave (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 Leave function which actually removes the channel from the array. More...
 
static void multiplexed_bridge_suspend (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 Suspend function which means control of the channel is going elsewhere. More...
 
static void multiplexed_bridge_unsuspend (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 Unsuspend function which means control of the channel is coming back to us. More...
 
static enum ast_bridge_write_result multiplexed_bridge_write (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 Write function for writing frames into the bridge. More...
 
static void multiplexed_nudge (struct multiplexed_thread *multiplexed_thread)
 Internal function which nudges the thread. More...
 
static void * multiplexed_thread_function (void *data)
 Thread function that executes for multiplexed threads. More...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Multiplexed two channel bridging module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_bridge_technology multiplexed_bridge
 
static struct ao2_containermultiplexed_threads
 Container of all operating multiplexed threads. More...
 

Detailed Description

Two channel bridging module which groups bridges into batches of threads.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file bridge_multiplexed.c.

Macro Definition Documentation

#define MULTIPLEXED_BUCKETS   53

Number of buckets our multiplexed thread container can have.

Definition at line 51 of file bridge_multiplexed.c.

Referenced by load_module().

#define MULTIPLEXED_MAX_CHANNELS   8

Number of channels we handle in a single thread.

Definition at line 54 of file bridge_multiplexed.c.

Referenced by find_multiplexed_thread(), and multiplexed_add_or_remove().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 425 of file bridge_multiplexed.c.

static void __unreg_module ( void  )
static

Definition at line 425 of file bridge_multiplexed.c.

static void destroy_multiplexed_thread ( void *  obj)
static

Destroy callback for a multiplexed thread structure.

Definition at line 83 of file bridge_multiplexed.c.

References multiplexed_thread::pipe.

Referenced by multiplexed_bridge_create().

84 {
86 
87  if (multiplexed_thread->pipe[0] > -1) {
88  close(multiplexed_thread->pipe[0]);
89  }
90  if (multiplexed_thread->pipe[1] > -1) {
91  close(multiplexed_thread->pipe[1]);
92  }
93 
94  return;
95 }
Structure which represents a single thread handling multiple 2 channel bridges.
static int find_multiplexed_thread ( void *  obj,
void *  arg,
int  flags 
)
static

Callback function for finding a free multiplexed thread.

Definition at line 76 of file bridge_multiplexed.c.

References CMP_MATCH, CMP_STOP, multiplexed_thread::count, and MULTIPLEXED_MAX_CHANNELS.

Referenced by multiplexed_bridge_create().

77 {
79  return (multiplexed_thread->count <= (MULTIPLEXED_MAX_CHANNELS - 2)) ? CMP_MATCH | CMP_STOP : 0;
80 }
Structure which represents a single thread handling multiple 2 channel bridges.
#define MULTIPLEXED_MAX_CHANNELS
Number of channels we handle in a single thread.
static int load_module ( void  )
static

Definition at line 416 of file bridge_multiplexed.c.

References ao2_container_alloc, ast_bridge_technology_register, AST_MODULE_LOAD_DECLINE, and MULTIPLEXED_BUCKETS.

417 {
420  }
421 
423 }
#define MULTIPLEXED_BUCKETS
Number of buckets our multiplexed thread container can have.
static struct ao2_container * multiplexed_threads
Container of all operating multiplexed threads.
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()
static struct ast_bridge_technology multiplexed_bridge
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
static void multiplexed_add_or_remove ( struct multiplexed_thread multiplexed_thread,
struct ast_channel chan,
int  add 
)
static

Helper function which adds or removes a channel and nudges the thread.

Definition at line 269 of file bridge_multiplexed.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, multiplexed_thread::chans, MULTIPLEXED_MAX_CHANNELS, multiplexed_nudge(), multiplexed_thread_function(), multiplexed_thread::service_count, multiplexed_thread::thread, and thread.

Referenced by multiplexed_bridge_join(), multiplexed_bridge_leave(), multiplexed_bridge_suspend(), and multiplexed_bridge_unsuspend().

270 {
271  int i, removed = 0;
272  pthread_t thread = AST_PTHREADT_NULL;
273 
274  ao2_lock(multiplexed_thread);
275 
276  multiplexed_nudge(multiplexed_thread);
277 
278  for (i = 0; i < MULTIPLEXED_MAX_CHANNELS; i++) {
279  if (multiplexed_thread->chans[i] == chan) {
280  if (!add) {
281  multiplexed_thread->chans[i] = NULL;
282  multiplexed_thread->service_count--;
283  removed = 1;
284  }
285  break;
286  } else if (!multiplexed_thread->chans[i] && add) {
287  multiplexed_thread->chans[i] = chan;
288  multiplexed_thread->service_count++;
289  break;
290  }
291  }
292 
293  if (multiplexed_thread->service_count && multiplexed_thread->thread == AST_PTHREADT_NULL) {
294  ao2_ref(multiplexed_thread, +1);
295  if (ast_pthread_create(&multiplexed_thread->thread, NULL, multiplexed_thread_function, multiplexed_thread)) {
296  ao2_ref(multiplexed_thread, -1);
297  ast_debug(1, "Failed to create an actual thread for multiplexed thread '%p', trying next time\n", multiplexed_thread);
298  }
299  } else if (!multiplexed_thread->service_count && multiplexed_thread->thread != AST_PTHREADT_NULL) {
300  thread = multiplexed_thread->thread;
301  multiplexed_thread->thread = AST_PTHREADT_STOP;
302  } else if (!add && removed) {
303  memmove(multiplexed_thread->chans + i, multiplexed_thread->chans + i + 1, sizeof(struct ast_channel *) * (MULTIPLEXED_MAX_CHANNELS - (i + 1)));
304  }
305 
306  ao2_unlock(multiplexed_thread);
307 
308  if (thread != AST_PTHREADT_NULL) {
309  pthread_join(thread, NULL);
310  }
311 
312  return;
313 }
pthread_t thread
Definition: app_meetme.c:962
Main Channel structure associated with a channel.
Definition: channel.h:742
#define MULTIPLEXED_MAX_CHANNELS
Number of channels we handle in a single thread.
struct ast_channel * chans[MULTIPLEXED_MAX_CHANNELS]
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
unsigned int service_count
static void * multiplexed_thread_function(void *data)
Thread function that executes for multiplexed threads.
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:418
#define AST_PTHREADT_STOP
Definition: lock.h:66
static void multiplexed_nudge(struct multiplexed_thread *multiplexed_thread)
Internal function which nudges the thread.
static int multiplexed_bridge_create ( struct ast_bridge bridge)
static

Create function which finds/reserves/references a multiplexed thread structure.

Definition at line 98 of file bridge_multiplexed.c.

References ao2_alloc, ao2_callback, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_log(), AST_PTHREADT_NULL, ast_bridge::bridge_pvt, multiplexed_thread::count, destroy_multiplexed_thread(), errno, find_multiplexed_thread(), LOG_WARNING, multiplexed_thread::pipe, and multiplexed_thread::thread.

99 {
101 
103 
104  /* Try to find an existing thread to handle our additional channels */
105  if (!(multiplexed_thread = ao2_callback(multiplexed_threads, 0, find_multiplexed_thread, NULL))) {
106  int flags;
107 
108  /* If we failed we will have to create a new one from scratch */
109  if (!(multiplexed_thread = ao2_alloc(sizeof(*multiplexed_thread), destroy_multiplexed_thread))) {
110  ast_debug(1, "Failed to find or create a new multiplexed thread for bridge '%p'\n", bridge);
112  return -1;
113  }
114 
115  multiplexed_thread->pipe[0] = multiplexed_thread->pipe[1] = -1;
116  /* Setup a pipe so we can poke the thread itself when needed */
117  if (pipe(multiplexed_thread->pipe)) {
118  ast_debug(1, "Failed to create a pipe for poking a multiplexed thread for bridge '%p'\n", bridge);
119  ao2_ref(multiplexed_thread, -1);
121  return -1;
122  }
123 
124  /* Setup each pipe for non-blocking operation */
125  flags = fcntl(multiplexed_thread->pipe[0], F_GETFL);
126  if (fcntl(multiplexed_thread->pipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
127  ast_log(LOG_WARNING, "Failed to setup first nudge pipe for non-blocking operation on %p (%d: %s)\n", bridge, errno, strerror(errno));
128  ao2_ref(multiplexed_thread, -1);
130  return -1;
131  }
132  flags = fcntl(multiplexed_thread->pipe[1], F_GETFL);
133  if (fcntl(multiplexed_thread->pipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
134  ast_log(LOG_WARNING, "Failed to setup second nudge pipe for non-blocking operation on %p (%d: %s)\n", bridge, errno, strerror(errno));
135  ao2_ref(multiplexed_thread, -1);
137  return -1;
138  }
139 
140  /* Set up default parameters */
141  multiplexed_thread->thread = AST_PTHREADT_NULL;
142 
143  /* Finally link us into the container so others may find us */
144  ao2_link(multiplexed_threads, multiplexed_thread);
145  ast_debug(1, "Created multiplexed thread '%p' for bridge '%p'\n", multiplexed_thread, bridge);
146  } else {
147  ast_debug(1, "Found multiplexed thread '%p' for bridge '%p'\n", multiplexed_thread, bridge);
148  }
149 
150  /* Bump the count of the thread structure up by two since the channels for this bridge will be joining shortly */
151  multiplexed_thread->count += 2;
152 
154 
155  bridge->bridge_pvt = multiplexed_thread;
156 
157  return 0;
158 }
static void destroy_multiplexed_thread(void *obj)
Destroy callback for a multiplexed thread structure.
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
Structure which represents a single thread handling multiple 2 channel bridges.
#define LOG_WARNING
Definition: logger.h:144
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:910
static struct ao2_container * multiplexed_threads
Container of all operating multiplexed threads.
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
int errno
static int find_multiplexed_thread(void *obj, void *arg, int flags)
Callback function for finding a free multiplexed thread.
void * bridge_pvt
Definition: bridging.h:163
static int multiplexed_bridge_destroy ( struct ast_bridge bridge)
static

Destroy function which unreserves/unreferences/removes a multiplexed thread structure.

Definition at line 181 of file bridge_multiplexed.c.

References ao2_lock, ao2_ref, ao2_unlink, ao2_unlock, ast_debug, ast_bridge::bridge_pvt, multiplexed_thread::count, and multiplexed_nudge().

182 {
184 
186 
187  multiplexed_thread->count -= 2;
188 
189  if (!multiplexed_thread->count) {
190  ast_debug(1, "Unlinking multiplexed thread '%p' since nobody is using it anymore\n", multiplexed_thread);
191  ao2_unlink(multiplexed_threads, multiplexed_thread);
192  }
193 
194  multiplexed_nudge(multiplexed_thread);
195 
197 
198  ao2_ref(multiplexed_thread, -1);
199 
200  return 0;
201 }
Structure which represents a single thread handling multiple 2 channel bridges.
static struct ao2_container * multiplexed_threads
Container of all operating multiplexed threads.
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
void * bridge_pvt
Definition: bridging.h:163
static void multiplexed_nudge(struct multiplexed_thread *multiplexed_thread)
Internal function which nudges the thread.
static int multiplexed_bridge_join ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Join function which actually adds the channel into the array to be monitored.

Definition at line 316 of file bridge_multiplexed.c.

References ast_channel_make_compatible(), ast_debug, AST_LIST_FIRST, AST_LIST_LAST, ast_bridge::bridge_pvt, ast_bridge_channel::chan, multiplexed_add_or_remove(), ast_channel::name, ast_channel::nativeformats, ast_channel::readformat, and ast_channel::writeformat.

317 {
318  struct ast_channel *c0 = AST_LIST_FIRST(&bridge->channels)->chan, *c1 = AST_LIST_LAST(&bridge->channels)->chan;
320 
321  ast_debug(1, "Adding channel '%s' to multiplexed thread '%p' for monitoring\n", bridge_channel->chan->name, multiplexed_thread);
322 
323  multiplexed_add_or_remove(multiplexed_thread, bridge_channel->chan, 1);
324 
325  /* If the second channel has not yet joined do not make things compatible */
326  if (c0 == c1) {
327  return 0;
328  }
329 
330  if (((c0->writeformat == c1->readformat) && (c0->readformat == c1->writeformat) && (c0->nativeformats == c1->nativeformats))) {
331  return 0;
332  }
333 
334  return ast_channel_make_compatible(c0, c1);
335 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
format_t writeformat
Definition: channel.h:854
Structure which represents a single thread handling multiple 2 channel bridges.
format_t nativeformats
Definition: channel.h:852
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: channel.h:787
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
struct ast_channel * chan
Definition: bridging.h:125
int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1)
Makes two channel formats compatible.
Definition: channel.c:5970
format_t readformat
Definition: channel.h:853
void * bridge_pvt
Definition: bridging.h:163
static void multiplexed_add_or_remove(struct multiplexed_thread *multiplexed_thread, struct ast_channel *chan, int add)
Helper function which adds or removes a channel and nudges the thread.
static int multiplexed_bridge_leave ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Leave function which actually removes the channel from the array.

Definition at line 338 of file bridge_multiplexed.c.

References ast_debug, ast_bridge::bridge_pvt, ast_bridge_channel::chan, multiplexed_add_or_remove(), and ast_channel::name.

339 {
341 
342  ast_debug(1, "Removing channel '%s' from multiplexed thread '%p'\n", bridge_channel->chan->name, multiplexed_thread);
343 
344  multiplexed_add_or_remove(multiplexed_thread, bridge_channel->chan, 0);
345 
346  return 0;
347 }
Structure which represents a single thread handling multiple 2 channel bridges.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: channel.h:787
struct ast_channel * chan
Definition: bridging.h:125
void * bridge_pvt
Definition: bridging.h:163
static void multiplexed_add_or_remove(struct multiplexed_thread *multiplexed_thread, struct ast_channel *chan, int add)
Helper function which adds or removes a channel and nudges the thread.
static void multiplexed_bridge_suspend ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Suspend function which means control of the channel is going elsewhere.

Definition at line 350 of file bridge_multiplexed.c.

References ast_debug, ast_bridge::bridge_pvt, ast_bridge_channel::chan, multiplexed_add_or_remove(), and ast_channel::name.

351 {
353 
354  ast_debug(1, "Suspending channel '%s' from multiplexed thread '%p'\n", bridge_channel->chan->name, multiplexed_thread);
355 
356  multiplexed_add_or_remove(multiplexed_thread, bridge_channel->chan, 0);
357 
358  return;
359 }
Structure which represents a single thread handling multiple 2 channel bridges.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: channel.h:787
struct ast_channel * chan
Definition: bridging.h:125
void * bridge_pvt
Definition: bridging.h:163
static void multiplexed_add_or_remove(struct multiplexed_thread *multiplexed_thread, struct ast_channel *chan, int add)
Helper function which adds or removes a channel and nudges the thread.
static void multiplexed_bridge_unsuspend ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Unsuspend function which means control of the channel is coming back to us.

Definition at line 362 of file bridge_multiplexed.c.

References ast_debug, ast_bridge::bridge_pvt, ast_bridge_channel::chan, multiplexed_add_or_remove(), and ast_channel::name.

363 {
365 
366  ast_debug(1, "Unsuspending channel '%s' from multiplexed thread '%p'\n", bridge_channel->chan->name, multiplexed_thread);
367 
368  multiplexed_add_or_remove(multiplexed_thread, bridge_channel->chan, 1);
369 
370  return;
371 }
Structure which represents a single thread handling multiple 2 channel bridges.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const ast_string_field name
Definition: channel.h:787
struct ast_channel * chan
Definition: bridging.h:125
void * bridge_pvt
Definition: bridging.h:163
static void multiplexed_add_or_remove(struct multiplexed_thread *multiplexed_thread, struct ast_channel *chan, int add)
Helper function which adds or removes a channel and nudges the thread.
static enum ast_bridge_write_result multiplexed_bridge_write ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
)
static

Write function for writing frames into the bridge.

Definition at line 374 of file bridge_multiplexed.c.

References AST_BRIDGE_CHANNEL_STATE_WAIT, AST_BRIDGE_WRITE_FAILED, AST_BRIDGE_WRITE_SUCCESS, AST_LIST_FIRST, AST_LIST_LAST, ast_write(), ast_bridge_channel::chan, and ast_bridge_channel::state.

375 {
376  struct ast_bridge_channel *other;
377 
378  if (AST_LIST_FIRST(&bridge->channels) == AST_LIST_LAST(&bridge->channels)) {
380  }
381 
382  if (!(other = (AST_LIST_FIRST(&bridge->channels) == bridge_channel ? AST_LIST_LAST(&bridge->channels) : AST_LIST_FIRST(&bridge->channels)))) {
384  }
385 
386  if (other->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
387  ast_write(other->chan, frame);
388  }
389 
391 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:4916
struct ast_channel * chan
Definition: bridging.h:125
Structure that contains information regarding a channel in a bridge.
Definition: bridging.h:117
enum ast_bridge_channel_state state
Definition: bridging.h:123
static void multiplexed_nudge ( struct multiplexed_thread multiplexed_thread)
static

Internal function which nudges the thread.

Definition at line 161 of file bridge_multiplexed.c.

References ast_log(), AST_PTHREADT_NULL, LOG_ERROR, multiplexed_thread::pipe, multiplexed_thread::thread, and multiplexed_thread::waiting.

Referenced by multiplexed_add_or_remove(), and multiplexed_bridge_destroy().

162 {
163  int nudge = 0;
164 
165  if (multiplexed_thread->thread == AST_PTHREADT_NULL) {
166  return;
167  }
168 
169  if (write(multiplexed_thread->pipe[1], &nudge, sizeof(nudge)) != sizeof(nudge)) {
170  ast_log(LOG_ERROR, "We couldn't poke multiplexed thread '%p'... something is VERY wrong\n", multiplexed_thread);
171  }
172 
173  while (multiplexed_thread->waiting) {
174  sched_yield();
175  }
176 
177  return;
178 }
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void* multiplexed_thread_function ( void *  data)
static

Thread function that executes for multiplexed threads.

Definition at line 204 of file bridge_multiplexed.c.

References ao2_lock, ao2_ref, ao2_trylock, ao2_unlock, ast_bridge_handle_trip(), ast_debug, ast_log(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_waitfor_nandfds(), ast_channel::bridge, multiplexed_thread::chans, errno, first, LOG_WARNING, multiplexed_thread::pipe, multiplexed_thread::service_count, stop, multiplexed_thread::thread, and multiplexed_thread::waiting.

Referenced by multiplexed_add_or_remove().

205 {
206  struct multiplexed_thread *multiplexed_thread = data;
207  int fds = multiplexed_thread->pipe[0];
208 
209  ao2_lock(multiplexed_thread);
210 
211  ast_debug(1, "Starting actual thread for multiplexed thread '%p'\n", multiplexed_thread);
212 
213  while (multiplexed_thread->thread != AST_PTHREADT_STOP) {
214  struct ast_channel *winner = NULL, *first = multiplexed_thread->chans[0];
215  int to = -1, outfd = -1;
216 
217  /* Move channels around so not just the first one gets priority */
218  memmove(multiplexed_thread->chans, multiplexed_thread->chans + 1, sizeof(struct ast_channel *) * (multiplexed_thread->service_count - 1));
219  multiplexed_thread->chans[multiplexed_thread->service_count - 1] = first;
220 
221  multiplexed_thread->waiting = 1;
222  ao2_unlock(multiplexed_thread);
223  winner = ast_waitfor_nandfds(multiplexed_thread->chans, multiplexed_thread->service_count, &fds, 1, NULL, &outfd, &to);
224  multiplexed_thread->waiting = 0;
225  ao2_lock(multiplexed_thread);
226  if (multiplexed_thread->thread == AST_PTHREADT_STOP) {
227  break;
228  }
229 
230  if (outfd > -1) {
231  int nudge;
232 
233  if (read(multiplexed_thread->pipe[0], &nudge, sizeof(nudge)) < 0) {
234  if (errno != EINTR && errno != EAGAIN) {
235  ast_log(LOG_WARNING, "read() failed for pipe on multiplexed thread '%p': %s\n", multiplexed_thread, strerror(errno));
236  }
237  }
238  }
239  if (winner && winner->bridge) {
240  struct ast_bridge *bridge = winner->bridge;
241  int stop = 0;
242  ao2_unlock(multiplexed_thread);
243  while ((bridge = winner->bridge) && ao2_trylock(bridge)) {
244  sched_yield();
245  if (multiplexed_thread->thread == AST_PTHREADT_STOP) {
246  stop = 1;
247  break;
248  }
249  }
250  if (!stop && bridge) {
251  ast_bridge_handle_trip(bridge, NULL, winner, -1);
252  ao2_unlock(bridge);
253  }
254  ao2_lock(multiplexed_thread);
255  }
256  }
257 
258  multiplexed_thread->thread = AST_PTHREADT_NULL;
259 
260  ast_debug(1, "Stopping actual thread for multiplexed thread '%p'\n", multiplexed_thread);
261 
262  ao2_unlock(multiplexed_thread);
263  ao2_ref(multiplexed_thread, -1);
264 
265  return NULL;
266 }
Main Channel structure associated with a channel.
Definition: channel.h:742
Structure which represents a single thread handling multiple 2 channel bridges.
#define LOG_WARNING
Definition: logger.h:144
struct ast_channel * chans[MULTIPLEXED_MAX_CHANNELS]
unsigned int stop
Definition: app_meetme.c:969
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition: channel.c:3188
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
unsigned int service_count
void ast_bridge_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
Feed notification that a frame is waiting on a channel into the bridging core.
Definition: bridging.c:277
Structure that contains information about a bridge.
Definition: bridging.h:149
#define ao2_trylock(a)
Definition: astobj2.h:506
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_bridge * bridge
Definition: channel.h:865
int errno
#define AST_PTHREADT_STOP
Definition: lock.h:66
static int unload_module ( void  )
static

Definition at line 407 of file bridge_multiplexed.c.

References ao2_ref, and ast_bridge_technology_unregister().

408 {
410 
412 
413  return res;
414 }
static struct ao2_container * multiplexed_threads
Container of all operating multiplexed threads.
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
Definition: bridging.c:99
static struct ast_bridge_technology multiplexed_bridge

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Multiplexed two channel bridging module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 425 of file bridge_multiplexed.c.

Definition at line 425 of file bridge_multiplexed.c.

struct ast_bridge_technology multiplexed_bridge
static

Definition at line 393 of file bridge_multiplexed.c.

struct ao2_container* multiplexed_threads
static

Container of all operating multiplexed threads.

Definition at line 73 of file bridge_multiplexed.c.