* to continue.
*/
AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT = (1 << 22),
+ /*!
+ * The data on chan->timingdata is an astobj2 object.
+ */
+ AST_FLAG_TIMINGDATA_IS_AO2_OBJ = (1 << 23),
};
/*! \brief ast_bridge_config flags */
* \version 1.6.1 changed samples parameter to rate, accomodates new timing methods
*/
int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data);
+int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data, unsigned int is_ao2_obj);
/*!
* \brief Transfer a channel (if supported).
}
int ast_settimeout(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data)
+{
+ return ast_settimeout_full(c, rate, func, data, 0);
+}
+
+int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(const void *data), void *data, unsigned int is_ao2_obj)
{
int res;
unsigned int real_rate = rate, max_rate;
res = ast_timer_set_rate(c->timer, real_rate);
+ if (c->timingdata && ast_test_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
+ ao2_ref(c->timingdata, -1);
+ }
+
c->timingfunc = func;
c->timingdata = data;
+ if (data && is_ao2_obj) {
+ ao2_ref(data, 1);
+ ast_set_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
+ } else {
+ ast_clear_flag(c, AST_FLAG_TIMINGDATA_IS_AO2_OBJ);
+ }
+
if (func == NULL && rate == 0 && c->fdno == AST_TIMING_FD) {
/* Clearing the timing func and setting the rate to 0
* means that we don't want to be reading from the timingfd
/* save a copy of func/data before unlocking the channel */
int (*func)(const void *) = chan->timingfunc;
void *data = chan->timingdata;
+ int got_ref = 0;
+ if (data && ast_test_flag(chan, AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
+ ao2_ref(data, 1);
+ got_ref = 1;
+ }
chan->fdno = -1;
ast_channel_unlock(chan);
func(data);
+ if (got_ref) {
+ ao2_ref(data, -1);
+ }
} else {
ast_timer_set_rate(chan->timer, 0);
chan->fdno = -1;
rate = (unsigned int) roundf(samp_rate / ((float) whennext));
- ast_settimeout(s->owner, rate, ast_fsread_audio, s);
+ ast_settimeout_full(s->owner, rate, ast_fsread_audio, s, 1);
} else {
s->owner->streamid = ast_sched_add(s->owner->sched,
whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);