about code sinnept in APUE Chapter 11 about thread - Unix

This is a discussion on about code sinnept in APUE Chapter 11 about thread - Unix ; Hi folks. Recently I'm reading Chapter 11 about thread of APUE(Advanced Programming in UNIX Enviroment), I found that there're 3 errors that may occur when using code snippet given in Fig11.10 which I'll show below, but I don't if I'm ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: about code sinnept in APUE Chapter 11 about thread

  1. about code sinnept in APUE Chapter 11 about thread

    Hi folks.

    Recently I'm reading Chapter 11 about thread of APUE(Advanced
    Programming in UNIX Enviroment), I found that there're 3 errors that
    may occur when using code snippet given in Fig11.10 which I'll show
    below, but I don't if I'm
    right or not.

    /*------------------- code in APUE Fig11.10 --------------------*/
    #include
    #include

    struct foo {
    int f_count;
    pthread_mutex_t f_lock;
    /* ... more stuff here ... */
    };

    struct foo *
    foo_alloc(void) /* allocate the object */
    {
    struct foo *fp;

    if ((fp = malloc(sizeof(struct foo))) != NULL) {
    fp->f_count = 1;
    if (pthread_mutex_init(&fp->f_lock, NULL) != 0) {
    free(fp);
    return(NULL);
    }
    /* ... continue initialization ... */
    }
    return(fp);
    }

    void
    foo_hold(struct foo *fp) /* add a reference to the object */
    {
    pthread_mutex_lock(&fp->f_lock);
    fp->f_count++;
    pthread_mutex_unlock(&fp->f_lock);
    }

    void
    foo_rele(struct foo *fp) /* release a reference to the object */
    {
    pthread_mutex_lock(&fp->f_lock);
    if (--fp->f_count == 0) { /* last reference */
    pthread_mutex_unlock(&fp->f_lock);
    pthread_mutex_destroy(&fp->f_lock);
    free(fp);
    } else {
    pthread_mutex_unlock(&fp->f_lock);
    }
    }
    /*--------------------code written by myself to test the functions
    above-----------------------*/
    /*-------------------- no error handling for
    clear -----------------------*/
    static void *thr_fn(void *arg)
    {
    foo_hold((struct foo *)arg);
    foo_rele((struct foo *)arg);
    return (void *)0;
    }

    int main(int argc, char **argv)
    {
    pthread_t tid1;
    int err;
    struct foo *fp;

    fp = foo_alloc();
    pthread_create(&tid1, NULL, thr_fn, fp);
    foo_rele(fp);

    return 0;
    }

    The 3 errors are: (here I'll use "TA" to refer to the main thread,
    "TB" for the new thread)
    1. pthread_mutex_destroy(&fp->f_lock) in foo_rele() may fail.

    This may occur when execution flow looks like:
    ....->[TA; foo_rele; pthread_mutex_unlock]->[TB; foo_hold;
    pthread_mutex_lock]->[TA; foo_rele; pthread_mutex_destroy]

    2. pthread_mutex_lock(&fp->f_lock) in foo_hold() may fail.

    This may occur when execution flow looks like:
    ....->[TA; foo_rele; pthread_mutex_destroy]->[TB; foo_hold;
    pthread_mutex_lock]

    3. free(fp) in foo_rele() may be called twice thus causing memory
    error.
    This may occur when execution flow looks like:
    ....->[TA; foo_rele; pthread_mutex_unlock]->[TB; foo_hold;
    pthread_mutex_lock]->....->[TB; foo_hold; pthread_mutex_unlock]->...-
    >[TB; foo_rele; free(fp)]->[TA; foo_rele; free(fp)]


    Any idea? Am I right?

  2. Re: about code sinnept in APUE Chapter 11 about thread

    ɽ writes:

    [ APUE excerpt ]


    > /*--------------------code written by myself to test the functions
    > above-----------------------*/
    > /*-------------------- no error handling for
    > clear -----------------------*/
    > static void *thr_fn(void *arg)
    > {
    > foo_hold((struct foo *)arg);
    > foo_rele((struct foo *)arg);
    > return (void *)0;
    > }
    >
    > int main(int argc, char **argv)
    > {
    > pthread_t tid1;
    > int err;
    > struct foo *fp;
    >
    > fp = foo_alloc();
    > pthread_create(&tid1, NULL, thr_fn, fp);
    > foo_rele(fp);
    >
    > return 0;
    > }
    >
    > The 3 errors are:


    There is one error here: You are misusing the reference counter.

+ Reply to Thread