Absolutely agree, there is a race in code lines 317-320, and it's
possible that two threads will enter first if clause(line 317) and
make suspend_request negative, so suspended thread will never get
notified.

317     if(thread->suspend_request > 0) {
318         if (thread->safepoint_callback && thread->suspend_request
< 2) return;
319         apr_atomic_dec32((apr_uint32_t *)&(thread->suspend_request));
320         if(thread->suspend_request == 0) {
321             // Notify the thread that it may wake up now
322             hysem_post(thread->resume_event);
323             TRACE(("TM: resume one thread: %p request count:
%d",thread , thread->suspend_request));
324             thread->state &= ~TM_THREAD_STATE_SUSPENDED;


The code sample you've provided is exactly how this code chunk should
look like.
I'd like to comment only what's the second if clause means(line 318):

if safepoint callback(the function to be called on safe_point
entrance) set to non null value then we have suspend_request_count
value increased by one and additional resume will be send by
callback_processing mechanism after callback is processed.

I'll put your code into JIRA. Evgueni Brevnov, recently filled a
H-2648 issue against safepoint_callback mechanism, so this on will be
very good addendum to it.

Nik.


On 12/12/06, Weldon Washburn <[EMAIL PROTECTED]> wrote:
   - A question on hythread_resume()
      - Line 318:   " if (thread->safepoint_callback &&
      thread->suspend_request < 2) return"


    - is there ever the situation where "thread->suspend_request == 0 "
         ??
      -
      - is there a race condition in the use of
      "thread->suspend_request" in lines 318, 319, 320?
         - In specific, does it make sense to replace these lines
         of code with something like:



        int current_suspend_request_count;

        while (1) {

            current_suspend_request_count = thread->suspend_request;

if (thread->safepoint_callback && current_suspend_request_count < 2) return;

        int status = apr_atomic_casptr (current_suspend_request_count,
current_suspend_request--, ((apr_uint32_t *)&(thread->suspend_request);

        if(/*original thread->suspend_request*/ status == 1) {  /* thus the
new value has to be zero

            // Notify the thread that it may wake up now

            hysem_post(thread->resume_event);

            TRACE(("TM: resume one thread: %p request count: %d",thread ,
thread->suspend_request));

            thread->state &= ~TM_THREAD_STATE_SUSPENDED;

            break;


--
Weldon Washburn
Intel Enterprise Solutions Software Division


Reply via email to