apr-bugs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 48722] New: apr_thread_pool_push may not create a new thread when necessary
Date Wed, 10 Feb 2010 15:44:10 GMT
https://issues.apache.org/bugzilla/show_bug.cgi?id=48722

           Summary: apr_thread_pool_push may not create a new thread when
                    necessary
           Product: APR
           Version: HEAD
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: major
          Priority: P2
         Component: APR-util
        AssignedTo: bugs@apr.apache.org
        ReportedBy: M8R-udo4lc@safetymail.info


apr_thread_pool_push may fail to detect that the number of idle threads is zero
(because the threads did not update the counter yet). This is specially bad
when you have a task that is waiting for another to complete (dead-lock).

Example code:

#include <stdlib.h>
#include <apr.h>
#include <apr_thread_mutex.h>
#include <apr_thread_pool.h>
#include <apr_thread_cond.h>

/** structure sent to the thread-pool */
typedef struct st_thaux {
    apr_thread_mutex_t    *mutex;
    apr_thread_cond_t    *cond;
    int                    waiting;
    int                    flag;
} thaux;

/* creates an auxiliary structure and push it to the thread-pool */
#define DO_PUSH(aux) \
    aux=calloc(1,sizeof(thaux));\
    apr_thread_mutex_create(&aux->mutex,APR_THREAD_MUTEX_UNNESTED,mp);\
    apr_thread_cond_create(&aux->cond,mp);\
    apr_thread_pool_push(tp,tp_worker,(void*)aux,0,0x00);

/* notifies the auxiliary structure's conditional variable */
#define DO_NOTIFY(aux) \
    while (!aux->waiting) apr_sleep(10000);\
    apr_thread_mutex_lock(aux->mutex);\
    aux->flag=1;\
    apr_thread_cond_broadcast(aux->cond);\
    apr_thread_mutex_unlock(aux->mutex);

/* waits for the auxiliary structure's conditional variable to be notified */
#define DO_WAIT(aux) \
    aux->waiting=1;\
    apr_thread_mutex_lock(aux->mutex);\
    if (!aux->flag)
apr_thread_cond_timedwait(aux->cond,aux->mutex,apr_time_from_sec(1));\
    if (!aux->flag) {\
        printf("DEAD-LOCK DETECTED - aborting\n");\
        exit(1);\
    }\
    apr_thread_mutex_unlock(aux->mutex);


/** thread-pool function worker */
void *APR_THREAD_FUNC tp_worker(apr_thread_t *thptr,void *arg)
{
    DO_NOTIFY(((thaux*)arg));
    return((void*)thptr);
}

/* main entry point */
int main(int argc, char **argv)
{
    apr_pool_t        *mp        = 0x00;    /* memory pool */
    int                i        = 0;    /* run count */
    const int        THSTART    = 1;    /* number of threads to begin with */
    const int        THMAX    = 20;    /* maximum number of threads allowed */

    apr_initialize();
    apr_pool_initialize();

    printf("Starting test...\n");
    for (i=1; i<=100; i++) {
        apr_thread_pool_t    *tp        = 0x00;    /* thread pool */
        thaux                *aux1    = 0x00; /* task #1 */
        thaux                *aux2    = 0x00;    /* task #2 */

        printf("Run #%d\n",i);
        apr_pool_create(&mp,0x00);
        apr_thread_pool_create(&tp,THSTART,THMAX,mp);
        /* push both tasks */
        DO_PUSH(aux1);
        //apr_sleep(10000); // uncomment this line and see the results
        DO_PUSH(aux2);
        /* wait for the tasks to complete (but wait task #2 first)  */
        DO_WAIT(aux2);
        DO_WAIT(aux1);
        /* cleanup */
        free(aux1);aux1=0;
        free(aux2);aux2=0;
        apr_thread_pool_destroy(tp);tp=0;
        apr_pool_destroy(mp);mp=0;
    }
    printf("Test finished with success!\n");
    return 0;
}

-- 
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@apr.apache.org
For additional commands, e-mail: bugs-help@apr.apache.org


Mime
View raw message