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
...
-
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?
-
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.