This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]