This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: Cleaning up after timer_delete
Le samedi 25 juillet 2009 19:10:53 Carlos O'Donell, vous avez écrit :
> 2009/7/23 Rémi Denis-Courmont <remi@remlab.net>:
> > So in other words, I need to re-invent the wheel and create my own timer
> > subsystem?? :-(
>
> Could you please produce a testcase which shows the problem?
Consider this dummy library that prints a specified message to the console at
a specified interval. Here the main functions, calls the library and waits for
user to press Enter (error handling is ignored for simplicity).
----8<--------8<--------8<--------8<--------8<--------8<--------8<----
/* --- Library --- */
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
struct foo
{
timer_t timer;
char *str;
};
static void foo_timer(union sigval sival)
{
struct foo *f;
f = sival.sival_ptr;
puts (f->str);
}
struct foo *foo_start(const char *str, unsigned sec)
{
struct foo *f;
struct sigevent ev;
struct itimerspec it;
f = malloc(sizeof (*f));
f->str = strdup(str);
memset(&ev, 0, sizeof (ev));
ev.sigev_notify = SIGEV_THREAD;
ev.sigev_value.sival_ptr = f;
ev.sigev_notify_function = foo_timer;
ev.sigev_notify_attributes = NULL;
timer_create(CLOCK_MONOTONIC, &ev, &f->timer);
it.it_interval.tv_sec = sec;
it.it_interval.tv_nsec = 0;
it.it_value.tv_sec = 0;
it.it_value.tv_nsec = 1;
timer_settime(f->timer, 0, &it, NULL);
return f;
}
void foo_stop(struct foo *f)
{
timer_delete(f->timer);
free(f->str);
free(f);
}
/* --- Main program --- */
#include <unistd.h>
int main (int argc, const char *argv[])
{
struct foo *f;
f = foo_start ("Hello world!", 1);
getc (stdin);
foo_stop (f);
return 0;
}
----8<--------8<--------8<--------8<--------8<--------8<--------8<----
In my understanding, foo_stop() is buggy. If the user pressed enter while
foo_timer() is running, foo_timer() will end up reading memory that was free'd
by foo_stop(). This can happen because timer_delete() does NOT warranty that
pending occurences of the timer have been completed.
I'm wondering how to use interval timers from a library such that I can safely
clean up data after the timer is disarmed.
--
Rémi Denis-Courmont
http://www.remlab.net/