Below is a patch I'm using to deal with the non-thread-safety of the tuple_node data returned by pjsua_buddy_get_info.? I reported this issue to the list yesterday. It adds a new API call which calls a provided handler with the buddy_info, while guaranteeing that the buddy's lock is held during the operation.? I decided this was preferable to both exposing the lock_buddy call (prone to misuse) and deep-copying the tuple data (where to put it?). It also updates the pjsua_buddy_get_info documentation to warn against using the tuple_node data outside the context of an on_buddy_state callback, and directs the user to the new api call. Index: pjsip/include/pjsua-lib/pjsua.h =================================================================== --- pjsip/include/pjsua-lib/pjsua.h??? (1_0/pjproject-1.12)??? (revision 44318) +++ pjsip/include/pjsua-lib/pjsua.h??? (1_1/pjproject-1.12)??? (revision 44412) @@ -3895,6 +3895,11 @@ ?/** ? * Get detailed buddy info. ? * + * Note that the tuple_node data in info->pres_status should not be used + * unless the buddy's lock is held, such as in an on_buddy_state callback. + * See #pjsua_buddy_call_with_info() if this field is needed. + * + * ? * @param buddy_id??? The buddy identification. ? * @param info??? ??? Pointer to receive information about buddy. ? * @@ -3904,6 +3909,23 @@ ???? ??? ??? ??? ??? ? pjsua_buddy_info *info); ? ?/** + * Call a provided handler with detailed buddy info.? This can be useful + * when the tuple_node data from pres_status needs to be accessed, as it + * is otherwise not threadsafe. + * + * @param buddy_id??? The buddy identification. + * @param handler?????? Handler to be called with buddy information. + * @param handler_data? Arbitrary data to be passed to the handler. + * + * @return??? ??? PJ_SUCCESS on success, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsua_buddy_call_with_info(pjsua_buddy_id buddy_id, +??? ??? ??? ??? ??? ??????? void (*handler)( +????????????????????????????????????????????????????????? pjsua_buddy_id, +????????????????????????????????????????????????????????? pjsua_buddy_info *, +????????????????????????????????????????????????????????? void *handler_data), +??????????????????????????????????????????????? void *handler_data); +/** ? * Set the user data associated with the buddy object. ? * ? * @param buddy_id??? The buddy identification. Index: pjsip/src/pjsua-lib/pjsua_pres.c =================================================================== --- pjsip/src/pjsua-lib/pjsua_pres.c??? (1_0/pjproject-1.12)??? (revision 44318) +++ pjsip/src/pjsua-lib/pjsua_pres.c??? (1_1/pjproject-1.12)??? (revision 44412) @@ -216,7 +216,40 @@ ???? return PJ_SUCCESS; ?} ? +PJ_DEF(pj_status_t) pjsua_buddy_call_with_info( pjsua_buddy_id buddy_id, +??????????????????????????????????????????????? void (*handler)( +????????????????????????????????????????????????????????? pjsua_buddy_id, +????????????????????????????????????????????????????????? pjsua_buddy_info *, +????????????????????????????????????????????????????????? void *), +??????????????????????????????????????????????? void *handler_data) +{ +??? struct buddy_lock lck; +??? pjsua_buddy *buddy; +??? pj_status_t status; +??? +??? pjsua_buddy_info info; ? +??? PJ_ASSERT_RETURN(pjsua_buddy_is_valid(buddy_id), PJ_EINVAL); + +??? status = lock_buddy("pjsua_buddy_get_info()", buddy_id, &lck, 0); +??? if (status != PJ_SUCCESS) +??? return status; + +??? status = pjsua_buddy_get_info(buddy_id, &info); + +??? if (status != PJ_SUCCESS) { +??? unlock_buddy(&lck); +??????? return status; +??? } + +??? handler(buddy_id, &info, handler_data); + +??? unlock_buddy(&lck); +??? return PJ_SUCCESS; +} + + + ?/* ? * Get detailed buddy info. ? */ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20120228/3d45841d/attachment-0001.html>