summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-02-17 00:30:24 +0000
committerBenny Prijono <bennylp@teluu.com>2007-02-17 00:30:24 +0000
commit9ac7da457d1e6a61d2e5e0d73602f18c043022df (patch)
tree47ce3b851dddf27a3f8366b5c1789beb21c36444
parentee9a901efdc8fc3855e6cbf6ae0d67c9900d8872 (diff)
Fixed ticket #107: deadlock with ioqueue/IOCP unregistration when unregistration is done in the callback
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@958 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/src/pj/ioqueue_winnt.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/pjlib/src/pj/ioqueue_winnt.c b/pjlib/src/pj/ioqueue_winnt.c
index ae6bb70e..edbb5a16 100644
--- a/pjlib/src/pj/ioqueue_winnt.c
+++ b/pjlib/src/pj/ioqueue_winnt.c
@@ -666,6 +666,9 @@ static pj_bool_t poll_iocp( HANDLE hIocp, DWORD dwTimeout,
*/
PJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key )
{
+ unsigned i;
+ enum { RETRY = 10 };
+
PJ_ASSERT_RETURN(key, PJ_EINVAL);
#if PJ_HAS_TCP
@@ -713,7 +716,12 @@ PJ_DEF(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key )
* Forcing context switch seems to have fixed that, but this is quite
* an ugly solution..
*/
- while (pj_atomic_get(key->ref_count) != 1)
+ //This will loop forever if unregistration is done on the callback.
+ //Doing this with RETRY I think should solve the IOCP setting the
+ //socket signalled, without causing the deadlock.
+ //while (pj_atomic_get(key->ref_count) != 1)
+ // pj_thread_sleep(0);
+ for (i=0; pj_atomic_get(key->ref_count) != 1 && i<RETRY; ++i)
pj_thread_sleep(0);
/* Decrement reference counter to destroy the key. */
@@ -754,8 +762,11 @@ PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioqueue, const pj_time_val *timeout)
#if PJ_IOQUEUE_HAS_SAFE_UNREG
/* Check the closing keys only when there's no activity and when there are
* pending closing keys.
+ * blp:
+ * no, always check the list. Otherwise on busy activity, this will cause
+ * ioqueue to reject new registration.
*/
- if (event_count == 0 && !pj_list_empty(&ioqueue->closing_list)) {
+ if (/*event_count == 0 &&*/ !pj_list_empty(&ioqueue->closing_list)) {
pj_time_val now;
pj_ioqueue_key_t *key;