RFR(S): 8073042: jcmd hangs until another jcmd is executed (which, in turn, also hangs) (on Windows)
Markus Gronlund
markus.gronlund at oracle.com
Mon Mar 2 15:49:10 UTC 2015
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 at 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
>
More information about the serviceability-dev
mailing list