Hi Jaroslav, Thanks for taking a look.
"So, if the number of enqueue request is higher than the max semaphore count it will just fail with the assert?" I am letting the max semaphore count reflect the number of available (also pre-allocated) operations - a client should not be able to reach this code if there are max semaphore count outstanding ops (it should not be able to get a valid op from available()). Thanks again Markus -----Original Message----- From: Jaroslav Bachorik Sent: den 2 mars 2015 14:44 To: serviceability-dev@openjdk.java.net Subject: Re: RFR(S): 8073042: jcmd hangs until another jcmd is executed (which, in turn, also hangs) (on Windows) Hi Markus, On 2.3.2015 13:34, Markus Gronlund wrote: > Greetings, > > Kindly asking for reviews for the following changeset: > > Bug: https://bugs.openjdk.java.net/browse/JDK-8073042 > > Webrev: http://cr.openjdk.java.net/~mgronlun/8073042/webrev01/ Looks reasonable. > > Description: > > The signaling mechanism used to communicate about attaching operations > under Windows currently only allows for a single outstanding item to > be visible. This leads to issues, such as the one described in this > bug, where clients assume their operations are under processing (they > have been enqueued after all), but the AttachListener thread does not > see, and hence do not process, these operations. > > Analysis: > > The _wakeup semaphore only allows for a single outstanding operation: > > CreateSemaphore(NULL, 0, 1, NULL); > > When a thread has enqueued an operation, it will notify the > AttachListener thread through the semaphore, by: > > ::ReleaseSemaphore(wakeup(), 1, NULL); // this increases the semaphore > count by 1 > > This will signal the semaphore and "wakeup" the AttachListener thread > which (most likely) is in WaitForSingleObject() for the semaphore to > become signaled. When the semaphore is signaled and AttachListener > returns from WaitForSingleObject(), the semaphore's count is > decremented, and the semaphore again becomes non-signaled (goes from > current count 1 (which is also maximum count) to zero). > > > Problem: multiple client threads will enqueue their operations if they > manage to get the list mutex() - if they do, they will insert their op > into the queue, and call: > > ::ReleaseSemaphore(wakeup(), 1, NULL); > > This means we could have two (or more) client threads having posted > operations, before the AttachListener thread becomes scheduled. > > Since the semaphore created has a maximum count == 1, any subsequent > calls to ::ReleaseSemaphore(wakeup(), 1, NULL);, taking the the > current count to > maximum count, will have _no_effect - the current > count of the semaphore remains at maximum count level AND > ::ReleaseSemaphore(wakeup(), 1, NULL); returns FALSE - but currently > there is no checking the return value here... > This means the client thread has managed to enqueue its op (and will > move into ConnectPipe()), but the AttachListener will never see more > than 1 enqueued op at any one time (hence it does not know it is > expected to process another operation and signal the associated pipe). > > This is how operations manage to get enqueued, but not processed until > another thread eventually signals the semaphore by posting another op. > > We must allow the semaphore to stay signaled when multiple ops are > enqueued - and since we only allow preallocate_count number of > operations to be enqueued, we can ensure the semaphore manages this > upper limit as its maximum count. So, if the number of enqueue request is higher than the max semaphore count it will just fail with the assert? Thanks, -JB- > > Tests: > > Jcmd/dcmd test > > Attach tests > > Thanks > > Markus >