diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-02-17 00:30:24 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-02-17 00:30:24 +0000 |
commit | 9ac7da457d1e6a61d2e5e0d73602f18c043022df (patch) | |
tree | 47ce3b851dddf27a3f8366b5c1789beb21c36444 /pjlib/src/pj/ioqueue_winnt.c | |
parent | ee9a901efdc8fc3855e6cbf6ae0d67c9900d8872 (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
Diffstat (limited to 'pjlib/src/pj/ioqueue_winnt.c')
-rw-r--r-- | pjlib/src/pj/ioqueue_winnt.c | 15 |
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; |