Changeset 5001

General spy cleanup.

Adding a new spy is now an O(1) operation.
Common some common code factored into a function.
- New public function:
cw_spy_get_frames: Get only the frames that both parts can give.

Committed by:  karvan
Date:  Jun 27 2008 * 15:38 (5 months ago)

Affected files:

callweaver/branches/karvan/apps/app_chanspy.c (unified diff)

r5000r5001
259259
260260 struct chanspy_translation_helper *csth = data;
261261 struct cw_frame frame, *f0, *f1, *f;
262 unsigned left, right;
263 unsigned same;
264 unsigned ii;
265262 int len0 = 0;
266263 int len1 = 0;
267264 int samp0 = 0;
------
281278
282279 len = sample * sizeof(int16_t);
283280
284 pthread_mutex_lock(&csth->spy.lock);
285 left = csth->spy.queue[0].count;
286 right = csth->spy.queue[1].count;
287 same = left < right ? left : right;
288 if (same == 0) {
289 pthread_mutex_unlock(&csth->spy.lock);
290 return 0;
291 }
292 ii = 0;
293 for (ii = 0, f0 = csth->spy.queue[0].head, f1 = csth->spy.queue[1].head ; ii < same; ++ii) {
294 f0 = f0->next;
295 f1 = f1->next;
296 }
297 f = csth->spy.queue[0].head;
298 csth->spy.queue[0].head = f0;
299 csth->spy.queue[0].count -= same;
300 if (!csth->spy.queue[0].count)
301 csth->spy.queue[0].tail = NULL;
302 f0 = f;
303 f = csth->spy.queue[1].head;
304 csth->spy.queue[1].head = f1;
305 csth->spy.queue[1].count -= same;
306 if (!csth->spy.queue[1].count)
307 csth->spy.queue[1].tail = NULL;
308 f1 = f;
309 pthread_mutex_unlock(&csth->spy.lock);
281 cw_spy_get_frames(&csth->spy, &f0, &f1);
310282 while (f0) {
311 struct cw_frame *f = f0->next;
283 struct cw_frame *f = f0->next;
312284 cw_slinfactory_feed(&csth->slinfactory[0], f0);
313285 cw_fr_free(f0);
314 f0 = f;
286 f0 = f;
315287 }
316288 while (f1) {
317 struct cw_frame *f = f1->next;
289 struct cw_frame *f = f1->next;
318290 cw_slinfactory_feed(&csth->slinfactory[1], f1);
319291 cw_fr_free(f1);
320 f1 = f;
292 f1 = f;
321293 }
322294
323295 if (csth->slinfactory[0].size < len || csth->slinfactory[1].size < len)
------
393365
394366 static void start_spying(struct cw_channel *chan, struct cw_channel *spychan, struct cw_channel_spy *spy)
395367 {
396
397 struct cw_channel_spy *cptr=NULL;
398368 struct cw_channel *peer;
399
400369 cw_log(LOG_WARNING, "Attaching %s to %s\n", spychan->name, chan->name);
401370
402371 cw_mutex_lock(&chan->lock);
403 if (chan->spiers)
404 {
405 for (cptr = chan->spiers; cptr && cptr->next; cptr = cptr->next)
406 ;
407 cptr->next = spy;
408 }
409 else
410 {
411 chan->spiers = spy;
412 }
372 spy->next = chan->spiers;
373 chan->spiers = spy;
413374 cw_mutex_unlock(&chan->lock);
414375 if ( cw_test_flag(chan, CW_FLAG_NBRIDGE) && (peer = cw_bridged_channel(chan)))
415376 cw_softhangup(peer, CW_SOFTHANGUP_UNBRIDGE);
------
439400 {
440401 chan->spiers = NULL;
441402 }
403 break;
442404 }
443405 prev = cptr;
444406 }

callweaver/branches/karvan/apps/app_muxmon.c (unified diff)

r4998r5001
152152 else
153153 chan->spiers = cptr->next;
154154 cptr->next = NULL;
155 break;
155156 }
156157 prev = cptr;
157158 }
------
168169 if (chan)
169170 {
170171 cw_mutex_lock(&chan->lock);
171 if (chan->spiers)
172 {
173 for (cptr = chan->spiers; cptr && cptr->next; cptr = cptr->next);
174 cptr->next = spy;
175 }
176 else
177 {
178 chan->spiers = spy;
179 }
172 spy->next = chan->spiers;
173 chan->spiers = spy;
180174 cw_mutex_unlock(&chan->lock);
181175
182176 if (cw_test_flag(chan, CW_FLAG_NBRIDGE) && (peer = cw_bridged_channel(chan)))
------
189183 struct cw_slinfactory *slinfactory1)
190184 {
191185 struct cw_frame *f, *f0, *f1;
192 unsigned left, right;
193 unsigned same;
194 unsigned ii;
195
196 pthread_mutex_lock(&spy->lock);
197 left = spy->queue[0].count;
198 right = spy->queue[1].count;
199 same = left < right ? left : right;
200 if (same == 0) {
201 pthread_mutex_unlock(&spy->lock);
202 return 0;
203 }
204 ii = 0;
205 for (ii = 0, f0 = spy->queue[0].head, f1 = spy->queue[1].head ; ii < same; ++ii) {
206 f0 = f0->next;
207 f1 = f1->next;
208 }
209 f = spy->queue[0].head;
210 spy->queue[0].head = f0;
211 spy->queue[0].count -= same;
212 if (!spy->queue[0].count)
213 spy->queue[0].tail = NULL;
214 f0 = f;
215 f = spy->queue[1].head;
216 spy->queue[1].head = f1;
217 spy->queue[1].count -= same;
218 if (!spy->queue[1].count)
219 spy->queue[1].tail = NULL;
220 f1 = f;
221 pthread_mutex_unlock(&spy->lock);
186
187 cw_spy_get_frames(spy, &f0, &f1);
222188 while (f0) {
223189 f = f0->next;
224190 cw_slinfactory_feed(slinfactory0, f0);
225191 cw_fr_free(f0);
226 f0 = f;
192 f0 = f;
227193 }
228194 while (f1) {
229195 f = f1->next;
230196 cw_slinfactory_feed(slinfactory1, f1);
231197 cw_fr_free(f1);
232 f1 = f;
198 f1 = f;
233199 }
234200 return 0;
235201 }

callweaver/branches/karvan/corelib/channel.c (unified diff)

r4997r5001
10741074 cw_device_state_changed_literal(name);
10751075 }
10761076
1077 /*--- cw_spy_get_frames: Get as many frames as BOTH parts can give. */
1078 /** Get as many frames as BOTH parts can give.
1079 * This will make \c f0 point to a list of frames from the first queue and \c f1
1080 * point to a list of frames from the second queue. Both list will have the same
1081 * number of elements.
1082 *
1083 * After calling this function the queues will have released the specified
1084 * frames and it's the caller's responsibility to deallocate them.
1085 *
1086 * @param spy The (unlocked) spy.
1087 * @param f0 The start of the frames from the first queue. This can become NULL
1088 * if no frames were available in either queue.
1089 * @param f1 The start of the frames from the second queue. This can become NULL
1090 * if no frames were available in either queue.
1091 */
1092 void cw_spy_get_frames(struct cw_channel_spy *spy, struct cw_frame **f0, struct cw_frame **f1)
1093 {
1094 unsigned left, right;
1095 unsigned same;
1096 cw_mutex_lock(&spy->lock);
1097 left = spy->queue[0].count;
1098 right = spy->queue[1].count;
1099 same = left < right ? left : right;
1100 if (same == 0) {
1101 *f0 = *f1 = NULL;
1102 } else {
1103 int ii;
1104 struct cw_frame *f = spy->queue[0].head;
1105 for (ii = 1; ii < same; ++ii)
1106 f = f->next;
1107 *f0 = spy->queue[0].head;
1108 spy->queue[0].head = f;
1109 spy->queue[0].count -= same;
1110 if (spy->queue[0].count == 0)
1111 spy->queue[0].tail = NULL;
1112 f = spy->queue[1].head;
1113 for (ii = 1; ii < same; ++ii)
1114 f = f->next;
1115 *f1 = spy->queue[1].head;
1116 spy->queue[1].head = f;
1117 spy->queue[1].count -= same;
1118 if (spy->queue[1].count == 0)
1119 spy->queue[1].tail = NULL;
1120 }
1121 cw_mutex_unlock(&spy->lock);
1122 }
1123
10771124 static void cw_spy_detach(struct cw_channel *chan)
10781125 {
10791126 struct cw_channel_spy *chanspy;
------
17571804 }
17581805 else
17591806 {
1760 if (chan->spiers)
1761 {
1762 struct cw_channel_spy *spying;
1807 struct cw_channel_spy *spying;
17631808
1764 for (spying = chan->spiers; spying; spying = spying->next)
1765 cw_queue_spy_frame(spying, f, 0);
1766 }
1809 for (spying = chan->spiers; spying; spying = spying->next)
1810 cw_queue_spy_frame(spying, f, 0);
17671811 if (chan->monitor && chan->monitor->read_stream)
17681812 {
17691813 #ifndef MONITOR_CONSTANT_DELAY
------
21912235 * let the channel driver use a writer thread
21922236 * to actually write the stuff, for example. */
21932237
2194 if (f->frametype == CW_FRAME_VOICE && chan->spiers)
2195 {
2238 if (f->frametype == CW_FRAME_VOICE) {
21962239 struct cw_channel_spy *spying;
2197
21982240 for (spying = chan->spiers; spying; spying = spying->next)
21992241 cw_queue_spy_frame(spying, f, 1);
22002242 }

callweaver/branches/karvan/include/callweaver/channel.h (unified diff)

r4997r5001
374374 /* Spy stuff */
375375 void cw_queue_spy_frame(struct cw_channel_spy *spy, struct cw_frame *f, int q);
376376 void cw_spy_empty_queues(struct cw_channel_spy *spy, struct cw_frame **f0,
377 struct cw_frame **f1);
377 struct cw_frame **f1);
378 void cw_spy_get_frames(struct cw_channel_spy *spy, struct cw_frame **f0,
379 struct cw_frame **f1);
378380
379381 /* Channel tech properties: */
380382 /* Channels have this property if they can accept input with jitter; i.e. most VoIP channels */