pjproject_bundled: timer: Clean up usage of timer heap
[asterisk/asterisk.git] / third-party / pjproject / patches / 0080-timer-Clean-up-usage-of-timer-heap.patch
1 From 853005378de2ffecee7774e095d8cbfbfa0ab706 Mon Sep 17 00:00:00 2001
2 From: George Joseph <gjoseph@digium.com>
3 Date: Tue, 2 Jan 2018 06:36:46 -0700
4 Subject: [PATCH] timer: Clean up usage of timer heap
5
6 Added a new pj_timer_entry_reset function that resets a timer_entry
7 for re-use.
8
9 Changed direct settings of timer_entry fields to use
10 pj_timer_entry_init and pj_timer_entry_reset.
11
12 Fixed issues where timers were being rescheduled incorrectly.
13 ---
14  pjlib/include/pj/timer.h             | 14 ++++++++++++++
15  pjlib/src/pj/ssl_sock_ossl.c         |  8 +++++---
16  pjlib/src/pj/timer.c                 | 12 ++++++++++++
17  pjnath/src/pjnath/ice_session.c      |  9 ++++++++-
18  pjnath/src/pjnath/nat_detect.c       |  2 ++
19  pjnath/src/pjnath/stun_sock.c        |  2 +-
20  pjnath/src/pjnath/stun_transaction.c | 10 +++++-----
21  pjnath/src/pjnath/turn_session.c     |  3 +++
22  pjnath/src/pjnath/turn_sock.c        |  1 +
23  pjnath/src/pjturn-srv/allocation.c   |  4 ++--
24  pjnath/src/pjturn-srv/listener_tcp.c |  2 +-
25  pjsip/src/pjsip-simple/evsub.c       |  6 +++---
26  pjsip/src/pjsip/sip_endpoint.c       |  4 +++-
27  pjsip/src/pjsip/sip_transaction.c    |  9 +++------
28  pjsip/src/pjsip/sip_transport.c      |  3 +--
29  15 files changed, 64 insertions(+), 25 deletions(-)
30
31 diff --git a/pjlib/include/pj/timer.h b/pjlib/include/pj/timer.h
32 index df6155a81..90fc8ac85 100644
33 --- a/pjlib/include/pj/timer.h
34 +++ b/pjlib/include/pj/timer.h
35 @@ -212,6 +212,20 @@ PJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
36                                                void *user_data,
37                                                pj_timer_heap_callback *cb );
38  
39 +/**
40 + * Reset a timer entry. Application should call this function before reusing
41 + * the timer entry.
42 + *
43 + * @param entry     The timer entry to be initialized.
44 + * @param id        Arbitrary ID assigned by the user/owner of this entry.
45 + *                  Applications can use this ID to distinguish multiple
46 + *                  timer entries that share the same callback and user_data.
47 + *
48 + * @return          The timer entry itself.
49 + */
50 +PJ_DECL(pj_timer_entry*) pj_timer_entry_reset( pj_timer_entry *entry,
51 +                                             int id);
52 +
53  /**
54   * Queries whether a timer entry is currently running.
55   *
56 diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
57 index 969cc1420..ead1a8fbb 100644
58 --- a/pjlib/src/pj/ssl_sock_ossl.c
59 +++ b/pjlib/src/pj/ssl_sock_ossl.c
60 @@ -291,6 +291,7 @@ struct pj_ssl_cert_t
61  static write_data_t* alloc_send_data(pj_ssl_sock_t *ssock, pj_size_t len);
62  static void free_send_data(pj_ssl_sock_t *ssock, write_data_t *wdata);
63  static pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock);
64 +static void on_timer(pj_timer_heap_t *th, struct pj_timer_entry *te);
65  
66  /*
67   *******************************************************************
68 @@ -1621,7 +1622,8 @@ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
69                     pj_timer_heap_cancel(ssock->param.timer_heap,
70                                          &ssock->timer);
71                 }
72 -               ssock->timer.id = TIMER_CLOSE;
73 +
74 +               pj_timer_entry_reset(&ssock->timer, TIMER_CLOSE);
75                 pj_time_val_normalize(&interval);
76                 if (pj_timer_heap_schedule(ssock->param.timer_heap, 
77                                            &ssock->timer, &interval) != 0)
78 @@ -2387,7 +2389,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
79         ssock->param.timeout.msec != 0))
80      {
81         pj_assert(ssock->timer.id == TIMER_NONE);
82 -       ssock->timer.id = TIMER_HANDSHAKE_TIMEOUT;
83 +       pj_timer_entry_reset(&ssock->timer, TIMER_HANDSHAKE_TIMEOUT);
84         status = pj_timer_heap_schedule(ssock->param.timer_heap, 
85                                         &ssock->timer,
86                                         &ssock->param.timeout);
87 @@ -3405,7 +3407,7 @@ PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock,
88         ssock->param.timeout.msec != 0))
89      {
90         pj_assert(ssock->timer.id == TIMER_NONE);
91 -       ssock->timer.id = TIMER_HANDSHAKE_TIMEOUT;
92 +       pj_timer_entry_reset(&ssock->timer, TIMER_HANDSHAKE_TIMEOUT);
93         status = pj_timer_heap_schedule(ssock->param.timer_heap,
94                                         &ssock->timer,
95                                         &ssock->param.timeout);
96 diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c
97 index 90a95e37b..13126116f 100644
98 --- a/pjlib/src/pj/timer.c
99 +++ b/pjlib/src/pj/timer.c
100 @@ -472,6 +472,18 @@ PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
101      return entry;
102  }
103  
104 +PJ_DEF(pj_timer_entry*) pj_timer_entry_reset( pj_timer_entry *entry,
105 +                                             int id)
106 +{
107 +    entry->id = id;
108 +    entry->_grp_lock = NULL;
109 +    entry->_timer_id = -1;
110 +    entry->_timer_value = (pj_time_val){0, 0};
111 +
112 +    return entry;
113 +}
114 +
115 +
116  PJ_DEF(pj_bool_t) pj_timer_entry_running( pj_timer_entry *entry )
117  {
118      return (entry->_timer_id >= 1);
119 diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c
120 index 63a0d1c9c..6d0e6abc9 100644
121 --- a/pjnath/src/pjnath/ice_session.c
122 +++ b/pjnath/src/pjnath/ice_session.c
123 @@ -1246,6 +1246,7 @@ done:
124                      ice->comp_cnt;
125         pj_time_val_normalize(&delay);
126  
127 +       pj_timer_entry_reset(&ice->timer, TIMER_KEEP_ALIVE);
128         pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
129                                           &ice->timer, &delay,
130                                           TIMER_KEEP_ALIVE,
131 @@ -1276,7 +1277,7 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
132         /* Call callback */
133         if (ice->cb.on_ice_complete) {
134             pj_time_val delay = {0, 0};
135 -
136 +           pj_timer_entry_reset(&ice->timer, TIMER_COMPLETION_CALLBACK);
137             pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
138                                               &ice->timer, &delay,
139                                               TIMER_COMPLETION_CALLBACK,
140 @@ -1507,6 +1508,7 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice,
141                     delay.sec = 0;
142                     delay.msec = ice->opt.controlled_agent_want_nom_timeout;
143                     pj_time_val_normalize(&delay);
144 +                   pj_timer_entry_reset(&ice->timer, TIMER_CONTROLLED_WAIT_NOM);
145  
146                     pj_timer_heap_schedule_w_grp_lock(
147                                         ice->stun_cfg.timer_heap,
148 @@ -1597,6 +1599,7 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice,
149         delay.sec = 0;
150         delay.msec = ice->opt.nominated_check_delay;
151         pj_time_val_normalize(&delay);
152 +        pj_timer_entry_reset(&ice->timer, TIMER_START_NOMINATED_CHECK);
153  
154         pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
155                                           &ice->timer, &delay,
156 @@ -1929,6 +1932,8 @@ static pj_status_t start_periodic_check(pj_timer_heap_t *th,
157         pj_time_val timeout = {0, PJ_ICE_TA_VAL};
158  
159         pj_time_val_normalize(&timeout);
160 +        pj_timer_entry_reset(&ice->timer, PJ_TRUE);
161 +
162         pj_timer_heap_schedule_w_grp_lock(th, te, &timeout, PJ_TRUE,
163                                           ice->grp_lock);
164      }
165 @@ -1986,6 +1991,7 @@ static void start_nominated_check(pj_ice_sess *ice)
166                                     &ice->clist.timer, PJ_FALSE);
167  
168      delay.sec = delay.msec = 0;
169 +    pj_timer_entry_reset(&ice->timer, PJ_TRUE);
170      status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
171                                                 &ice->clist.timer, &delay,
172                                                 PJ_TRUE,
173 @@ -2125,6 +2131,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_start_check(pj_ice_sess *ice)
174       * return start_periodic_check(ice->stun_cfg.timer_heap, &clist->timer);
175       */
176      delay.sec = delay.msec = 0;
177 +    pj_timer_entry_reset(&ice->timer, PJ_TRUE);
178      status = pj_timer_heap_schedule_w_grp_lock(ice->stun_cfg.timer_heap,
179                                                 &clist->timer, &delay,
180                                                 PJ_TRUE, ice->grp_lock);
181 diff --git a/pjnath/src/pjnath/nat_detect.c b/pjnath/src/pjnath/nat_detect.c
182 index 8a2408374..7bb364798 100644
183 --- a/pjnath/src/pjnath/nat_detect.c
184 +++ b/pjnath/src/pjnath/nat_detect.c
185 @@ -414,6 +414,7 @@ static void end_session(nat_detect_session *sess,
186      delay.msec = 0;
187  
188      sess->timer.id = TIMER_DESTROY;
189 +    pj_timer_entry_init(&sess->timer, TIMER_DESTROY, sess, &on_sess_timer);
190      pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay);
191  }
192  
193 @@ -933,6 +934,7 @@ static void on_sess_timer(pj_timer_heap_t *th,
194  
195         if (next_timer) {
196             pj_time_val delay = {0, TEST_INTERVAL};
197 +           pj_timer_entry_reset(te, TIMER_TEST);
198             pj_timer_heap_schedule(th, te, &delay);
199         } else {
200             te->id = 0;
201 diff --git a/pjnath/src/pjnath/stun_sock.c b/pjnath/src/pjnath/stun_sock.c
202 index 6028e0c47..3aab27a1d 100644
203 --- a/pjnath/src/pjnath/stun_sock.c
204 +++ b/pjnath/src/pjnath/stun_sock.c
205 @@ -864,7 +864,7 @@ static void start_ka_timer(pj_stun_sock *stun_sock)
206  
207         delay.sec = stun_sock->ka_interval;
208         delay.msec = 0;
209 -
210 +       pj_timer_entry_reset(&stun_sock->ka_timer, PJ_TRUE);
211         pj_timer_heap_schedule_w_grp_lock(stun_sock->stun_cfg.timer_heap,
212                                           &stun_sock->ka_timer,
213                                           &delay, PJ_TRUE,
214 diff --git a/pjnath/src/pjnath/stun_transaction.c b/pjnath/src/pjnath/stun_transaction.c
215 index 28f623005..ad87b7b6c 100644
216 --- a/pjnath/src/pjnath/stun_transaction.c
217 +++ b/pjnath/src/pjnath/stun_transaction.c
218 @@ -86,11 +86,8 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_create(pj_stun_config *cfg,
219      tsx->grp_lock = grp_lock;
220      pj_memcpy(&tsx->cb, cb, sizeof(*cb));
221  
222 -    tsx->retransmit_timer.cb = &retransmit_timer_callback;
223 -    tsx->retransmit_timer.user_data = tsx;
224 -
225 -    tsx->destroy_timer.cb = &destroy_timer_callback;
226 -    tsx->destroy_timer.user_data = tsx;
227 +    pj_timer_entry_init(&tsx->retransmit_timer, 0, tsx, &retransmit_timer_callback);
228 +    pj_timer_entry_init(&tsx->destroy_timer, 0, tsx, &destroy_timer_callback);
229  
230      pj_ansi_snprintf(tsx->obj_name, sizeof(tsx->obj_name), "utsx%p", tsx);
231  
232 @@ -120,6 +117,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_schedule_destroy(
233      pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->retransmit_timer,
234                                     TIMER_INACTIVE);
235  
236 +    pj_timer_entry_reset(&tsx->destroy_timer, TIMER_ACTIVE);
237      status = pj_timer_heap_schedule_w_grp_lock(tsx->timer_heap,
238                                                 &tsx->destroy_timer, delay,
239                                                 TIMER_ACTIVE, tsx->grp_lock);
240 @@ -237,6 +235,7 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx,
241          * cancel it (as opposed to when schedule_timer() failed we cannot
242          * cancel transmission).
243          */;
244 +       pj_timer_entry_reset(&tsx->retransmit_timer, TIMER_ACTIVE);
245         status = pj_timer_heap_schedule_w_grp_lock(tsx->timer_heap,
246                                                    &tsx->retransmit_timer,
247                                                    &tsx->retransmit_time,
248 @@ -315,6 +314,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx,
249          * cancel it (as opposed to when schedule_timer() failed we cannot
250          * cancel transmission).
251          */;
252 +        pj_timer_entry_reset(&tsx->retransmit_timer, TIMER_ACTIVE);
253         status = pj_timer_heap_schedule_w_grp_lock(tsx->timer_heap,
254                                                    &tsx->retransmit_timer,
255                                                    &tsx->retransmit_time,
256 diff --git a/pjnath/src/pjnath/turn_session.c b/pjnath/src/pjnath/turn_session.c
257 index bbea027f3..e4685e625 100644
258 --- a/pjnath/src/pjnath/turn_session.c
259 +++ b/pjnath/src/pjnath/turn_session.c
260 @@ -431,6 +431,7 @@ static void sess_shutdown(pj_turn_session *sess,
261  
262         pj_timer_heap_cancel_if_active(sess->timer_heap, &sess->timer,
263                                        TIMER_NONE);
264 +       pj_timer_entry_reset(&sess->timer, TIMER_DESTROY);
265         pj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer,
266                                           &delay, TIMER_DESTROY,
267                                           sess->grp_lock);
268 @@ -1434,6 +1435,7 @@ static void on_allocate_success(pj_turn_session *sess,
269         timeout.sec = sess->ka_interval;
270         timeout.msec = 0;
271  
272 +       pj_timer_entry_reset(&sess->timer, TIMER_KEEP_ALIVE);
273         pj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer,
274                                           &timeout, TIMER_KEEP_ALIVE,
275                                           sess->grp_lock);
276 @@ -2080,6 +2082,7 @@ static void on_timer_event(pj_timer_heap_t *th, pj_timer_entry *e)
277             delay.sec = sess->ka_interval;
278             delay.msec = 0;
279  
280 +           pj_timer_entry_reset(&sess->timer, TIMER_KEEP_ALIVE);
281             pj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer,
282                                               &delay, TIMER_KEEP_ALIVE,
283                                               sess->grp_lock);
284 diff --git a/pjnath/src/pjnath/turn_sock.c b/pjnath/src/pjnath/turn_sock.c
285 index a30ab5153..507858048 100644
286 --- a/pjnath/src/pjnath/turn_sock.c
287 +++ b/pjnath/src/pjnath/turn_sock.c
288 @@ -928,6 +928,7 @@ static void turn_on_state(pj_turn_session *sess,
289  
290         pj_timer_heap_cancel_if_active(turn_sock->cfg.timer_heap,
291                                        &turn_sock->timer, 0);
292 +       pj_timer_entry_reset(&turn_sock->timer, TIMER_DESTROY);
293         pj_timer_heap_schedule_w_grp_lock(turn_sock->cfg.timer_heap,
294                                           &turn_sock->timer,
295                                           &delay, TIMER_DESTROY,
296 diff --git a/pjnath/src/pjturn-srv/allocation.c b/pjnath/src/pjturn-srv/allocation.c
297 index 6c9c9ce11..88533926b 100644
298 --- a/pjnath/src/pjturn-srv/allocation.c
299 +++ b/pjnath/src/pjturn-srv/allocation.c
300 @@ -513,7 +513,7 @@ static void alloc_shutdown(pj_turn_allocation *alloc)
301       */
302  
303      /* Schedule destroy timer */
304 -    alloc->relay.timer.id = TIMER_ID_DESTROY;
305 +    pj_timer_entry_reset(&alloc->relay.timer, TIMER_ID_DESTROY);
306      pj_timer_heap_schedule(alloc->server->core.timer_heap,
307                            &alloc->relay.timer, &destroy_delay);
308  }
309 @@ -538,7 +538,7 @@ static pj_status_t resched_timeout(pj_turn_allocation *alloc)
310      delay.sec = alloc->relay.lifetime;
311      delay.msec = 0;
312  
313 -    alloc->relay.timer.id = TIMER_ID_TIMEOUT;
314 +    pj_timer_entry_reset(&alloc->relay.timer, TIMER_ID_TIMEOUT);
315      status = pj_timer_heap_schedule(alloc->server->core.timer_heap,
316                                     &alloc->relay.timer, &delay);
317      if (status != PJ_SUCCESS) {
318 diff --git a/pjnath/src/pjturn-srv/listener_tcp.c b/pjnath/src/pjturn-srv/listener_tcp.c
319 index 796ed471b..4a9550c2e 100644
320 --- a/pjnath/src/pjturn-srv/listener_tcp.c
321 +++ b/pjnath/src/pjturn-srv/listener_tcp.c
322 @@ -475,7 +475,7 @@ static void tcp_dec_ref(pj_turn_transport *tp,
323  
324      if (tcp->ref_cnt == 0 && tcp->timer.id == TIMER_NONE) {
325         pj_time_val delay = { SHUTDOWN_DELAY, 0 };
326 -       tcp->timer.id = TIMER_DESTROY;
327 +       pj_timer_entry_reset(&tcp->timer, TIMER_DESTROY);
328         pj_timer_heap_schedule(tcp->base.listener->server->core.timer_heap,
329                                &tcp->timer, &delay);
330      }
331 diff --git a/pjsip/src/pjsip-simple/evsub.c b/pjsip/src/pjsip-simple/evsub.c
332 index eb666654f..7748853d2 100644
333 --- a/pjsip/src/pjsip-simple/evsub.c
334 +++ b/pjsip/src/pjsip-simple/evsub.c
335 @@ -518,6 +518,7 @@ static void set_timer( pjsip_evsub *sub, int timer_id,
336         timeout.sec = seconds;
337         timeout.msec = 0;
338  
339 +       pj_timer_entry_reset(&sub->timer, timer_id);
340         pj_timer_heap_schedule_w_grp_lock(
341                             pjsip_endpt_get_timer_heap(sub->endpt),
342                             &sub->timer, &timeout, timer_id, sub->grp_lock);
343 @@ -655,7 +656,7 @@ static void on_timer( pj_timer_heap_t *timer_heap,
344      /* If this timer entry has just been rescheduled or cancelled
345       * while waiting for dialog mutex, just return (see #1885 scenario 1).
346       */
347 -    if (pj_timer_entry_running(entry) || entry->id == TIMER_TYPE_NONE) {
348 +    if (entry->id == TIMER_TYPE_NONE) {
349         pjsip_dlg_dec_lock(sub->dlg);
350         return;
351      }
352 @@ -786,8 +787,7 @@ static pj_status_t evsub_create( pjsip_dialog *dlg,
353                   pjsip_hdr_clone(sub->pool, pkg->pkg_accept);
354      pj_list_init(&sub->sub_hdr_list);
355  
356 -    sub->timer.user_data = sub;
357 -    sub->timer.cb = &on_timer;
358 +    pj_timer_entry_init(&sub->timer, 0, sub, &on_timer);
359  
360      /* Set name. */
361      pj_ansi_snprintf(sub->obj_name, PJ_ARRAY_SIZE(sub->obj_name),
362 diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
363 index d810781d5..5c98a5bf6 100644
364 --- a/pjsip/src/pjsip/sip_endpoint.c
365 +++ b/pjsip/src/pjsip/sip_endpoint.c
366 @@ -788,6 +788,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_schedule_timer_dbg(pjsip_endpoint *endpt,
367  {
368      PJ_LOG(6, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",
369                          entry, delay->sec, delay->msec));
370 +    pj_timer_entry_reset(entry, entry->id);
371      return pj_timer_heap_schedule_dbg(endpt->timer_heap, entry, delay,
372                                        src_file, src_line);
373  }
374 @@ -798,6 +799,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_schedule_timer( pjsip_endpoint *endpt,
375  {
376      PJ_LOG(6, (THIS_FILE, "pjsip_endpt_schedule_timer(entry=%p, delay=%u.%u)",
377                          entry, delay->sec, delay->msec));
378 +    pj_timer_entry_reset(entry, entry->id);
379      return pj_timer_heap_schedule( endpt->timer_heap, entry, delay );
380  }
381  #endif
382 @@ -809,7 +811,7 @@ PJ_DEF(void) pjsip_endpt_cancel_timer( pjsip_endpoint *endpt,
383                                        pj_timer_entry *entry )
384  {
385      PJ_LOG(6, (THIS_FILE, "pjsip_endpt_cancel_timer(entry=%p)", entry));
386 -    pj_timer_heap_cancel( endpt->timer_heap, entry );
387 +    pj_timer_heap_cancel_if_active( endpt->timer_heap, entry, 0 );
388  }
389  
390  /*
391 diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
392 index d52b12a72..5236e63f7 100644
393 --- a/pjsip/src/pjsip/sip_transaction.c
394 +++ b/pjsip/src/pjsip/sip_transaction.c
395 @@ -978,6 +978,7 @@ static pj_status_t tsx_schedule_timer(pjsip_transaction *tsx,
396      pj_status_t status;
397  
398      pj_assert(active_id != 0);
399 +    pj_timer_entry_reset(entry, active_id);
400      status = pj_timer_heap_schedule_w_grp_lock(timer_heap, entry,
401                                                 delay, active_id,
402                                                 tsx->grp_lock);
403 @@ -1019,12 +1020,8 @@ static pj_status_t tsx_create( pjsip_module *tsx_user,
404      pj_memcpy(pool->obj_name, tsx->obj_name, sizeof(pool->obj_name));
405  
406      tsx->handle_200resp = 1;
407 -    tsx->retransmit_timer.id = TIMER_INACTIVE;
408 -    tsx->retransmit_timer.user_data = tsx;
409 -    tsx->retransmit_timer.cb = &tsx_timer_callback;
410 -    tsx->timeout_timer.id = TIMER_INACTIVE;
411 -    tsx->timeout_timer.user_data = tsx;
412 -    tsx->timeout_timer.cb = &tsx_timer_callback;
413 +    pj_timer_entry_init(&tsx->retransmit_timer, TIMER_INACTIVE, tsx, &tsx_timer_callback);
414 +    pj_timer_entry_init(&tsx->timeout_timer, TIMER_INACTIVE, tsx, &tsx_timer_callback);
415      
416      if (grp_lock) {
417         tsx->grp_lock = grp_lock;
418 diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
419 index 3d27d5d71..834babeae 100644
420 --- a/pjsip/src/pjsip/sip_transport.c
421 +++ b/pjsip/src/pjsip/sip_transport.c
422 @@ -1092,8 +1092,7 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
423      /* Init. */
424      tp->tpmgr = mgr;
425      pj_bzero(&tp->idle_timer, sizeof(tp->idle_timer));
426 -    tp->idle_timer.user_data = tp;
427 -    tp->idle_timer.cb = &transport_idle_callback;
428 +    pj_timer_entry_init(&tp->idle_timer, 0, tp, &transport_idle_callback);
429  
430      /* 
431       * Register to hash table (see Trac ticket #42).
432 -- 
433 2.14.3
434