Fix dangling pointers causing erratic timer behaviour (affects taskbar with spacing); use calloc instead of malloc for safer initializations

git-svn-id: http://tint2.googlecode.com/svn/trunk@758 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
This commit is contained in:
o9000 2015-04-17 20:17:25 +00:00 committed by mrovi9000@gmail.com
parent 778b9f0ebf
commit 66cae4bb7c
17 changed files with 135 additions and 123 deletions

View file

@ -2,26 +2,38 @@
# For information on manually configuring tint2 see http://code.google.com/p/tint2/wiki/Configure
# Background definitions
# ID 1
# Background 1: panel
rounded = 7
border_width = 2
border_width = 1
background_color = #000000 60
border_color = #FFFFFF 16
# ID 2
# Background 2: normal/iconified tasks
rounded = 5
border_width = 0
background_color = #777777 40
border_color = #FFFFFF 48
background_color = #777777 20
border_color = #777777 30
# ID 3
# Background 3: active tasks
rounded = 5
border_width = 1
background_color = #777777 40
border_color = #FFFFFF 60
background_color = #777777 20
border_color = #ffffff 40
# Background 4: urgent tasks
rounded = 5
border_width = 1
background_color = #aa4400 100
border_color = #aa7733 100
# Background 5: tooltips
rounded = 2
border_width = 1
background_color = #ffffaa 100
border_color = #999999 100
# Panel
panel_items = LTSC
panel_items = LTSBC
panel_monitor = all
panel_position = bottom center horizontal
panel_size = 95% 30
@ -34,8 +46,8 @@ panel_background_id = 1
# Panel Autohide
autohide = 0
autohide_show_timeout = 0.3
autohide_hide_timeout = 2
autohide_show_timeout = 0
autohide_hide_timeout = 0.5
autohide_height = 2
strut_policy = follow_size
@ -63,13 +75,13 @@ task_maximum_size = 140 35
task_padding = 6 2
task_background_id = 2
task_active_background_id = 3
task_urgent_background_id = 2
task_urgent_background_id = 4
task_iconified_background_id = 2
task_tooltip = 0
task_tooltip = 1
urgent_nb_of_blink = 100000
# Task Icons
task_icon_asb = 80 0 0
task_icon_asb = 100 0 0
task_active_icon_asb = 100 0 0
task_urgent_icon_asb = 100 0 0
task_iconified_icon_asb = 70 0 0
@ -86,8 +98,8 @@ font_shadow = 0
mouse_left = toggle_iconify
mouse_middle = none
mouse_right = close
mouse_scroll_up = toggle
mouse_scroll_down = iconify
mouse_scroll_up = prev_task
mouse_scroll_down = next_task
# System Tray
systray_padding = 0 4 5
@ -101,18 +113,18 @@ time1_format = %H:%M
time1_font = sans 8
time2_format = %A %d %B
time2_font = sans 7
clock_font_color = #FFFFFF 74
clock_font_color = #FFFFFF 90
clock_padding = 1 0
clock_background_id = 0
clock_rclick_command = orage
# Tooltips
tooltip_padding = 2 2
tooltip_show_timeout = 0.7
tooltip_hide_timeout = 0.3
tooltip_background_id = 1
tooltip_font = sans 10
tooltip_font_color = #000000 80
tooltip_show_timeout = 0.5
tooltip_hide_timeout = 0.1
tooltip_background_id = 5
tooltip_font = sans 9
tooltip_font_color = #222222 100
# Battery
battery_low_status = 10
@ -120,7 +132,7 @@ battery_low_cmd = notify-send "battery low"
battery_hide = 98
bat1_font = sans 8
bat2_font = sans 6
battery_font_color = #FFFFFF 74
battery_font_color = #FFFFFF 94
battery_padding = 1 0
battery_background_id = 0

View file

@ -274,9 +274,8 @@ void init_battery()
}
#endif
if (battery_timeout == 0) {
battery_timeout = add_timeout(10, 10000, update_battery_tick, 0);
}
if (!battery_timeout)
battery_timeout = add_timeout(10, 10000, update_battery_tick, 0, &battery_timeout);
}

View file

@ -152,9 +152,9 @@ void init_clock()
if (!clock_timeout) {
if (time_format_needs_sec_ticks(time1_format) ||
time_format_needs_sec_ticks(time2_format)) {
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0);
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0, &clock_timeout);
} else {
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0);
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0, &clock_timeout);
}
}
}

View file

@ -52,7 +52,7 @@ void expand_exec(DesktopEntry *entry, const char *path)
// %c -> Name
// %k -> path
if (entry->exec) {
char *exec2 = malloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100);
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100, 1);
char *p, *q;
// p will never point to an escaped char
for (p = entry->exec, q = exec2; *p; p++, q++) {

View file

@ -561,8 +561,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
char *theme_name = ((IconTheme*)theme->data)->name;
char *dir_name = ((IconThemeDir*)dir->data)->name;
char *extension = (char*) ext->data;
char *file_name = malloc(strlen(base_name) + strlen(theme_name) +
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100);
char *file_name = calloc(strlen(base_name) + strlen(theme_name) +
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100, 1);
// filename = directory/$(themename)/subdirectory/iconname.extension
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
if (DEBUG_ICON_SEARCH)
@ -620,8 +620,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
for (ext = extensions; ext; ext = g_slist_next(ext)) {
char *base_name = (char*) base->data;
char *extension = (char*) ext->data;
char *file_name = malloc(strlen(base_name) + strlen(icon_name) +
strlen(extension) + 100);
char *file_name = calloc(strlen(base_name) + strlen(icon_name) +
strlen(extension) + 100, 1);
// filename = directory/iconname.extension
sprintf(file_name, "%s/%s%s", base_name, icon_name, extension);
if (DEBUG_ICON_SEARCH)

View file

@ -391,7 +391,7 @@ void free_icon(Imlib_Image icon)
void launcher_action(LauncherIcon *icon, XEvent* evt)
{
char *cmd = malloc(strlen(icon->cmd) + 10);
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
sprintf(cmd, "(%s&)", icon->cmd);
#if HAVE_SN
SnLauncherContext* ctx;

View file

@ -235,14 +235,14 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
goto out;
}
setting = malloc (sizeof *setting);
setting = calloc (1, sizeof *setting);
if (!setting) {
result = XSETTINGS_NO_MEM;
goto out;
}
setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */
setting->name = malloc (name_len + 1);
setting->name = calloc (name_len + 1, 1);
if (!setting->name) {
result = XSETTINGS_NO_MEM;
goto out;
@ -276,7 +276,7 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
goto out;
}
setting->data.v_string = malloc (v_int + 1);
setting->data.v_string = calloc (v_int + 1, 1);
if (!setting->data.v_string) {
result = XSETTINGS_NO_MEM;
goto out;
@ -400,7 +400,7 @@ XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNo
{
XSettingsClient *client;
client = malloc (sizeof *client);
client = calloc (1, sizeof *client);
if (!client)
return NULL;

View file

@ -34,12 +34,12 @@ xsettings_setting_copy (XSettingsSetting *setting)
XSettingsSetting *result;
size_t str_len;
result = malloc (sizeof *result);
result = calloc (1, sizeof *result);
if (!result)
return NULL;
str_len = strlen (setting->name);
result->name = malloc (str_len + 1);
result->name = calloc (str_len + 1, 1);
if (!result->name)
goto err;
@ -57,7 +57,7 @@ xsettings_setting_copy (XSettingsSetting *setting)
break;
case XSETTINGS_TYPE_STRING:
str_len = strlen (setting->data.v_string);
result->data.v_string = malloc (str_len + 1);
result->data.v_string = calloc (str_len + 1, 1);
if (!result->data.v_string)
goto err;
@ -90,7 +90,7 @@ xsettings_list_copy (XSettingsList *list)
{
XSettingsList *new_node;
new_node = malloc (sizeof *new_node);
new_node = calloc (1, sizeof *new_node);
if (!new_node)
goto error;
@ -180,7 +180,7 @@ xsettings_list_insert (XSettingsList **list,
XSettingsList *iter;
XSettingsList *last = NULL;
node = malloc (sizeof *node);
node = calloc (1, sizeof *node);
if (!node)
return XSETTINGS_NO_MEM;
node->setting = setting;

View file

@ -126,6 +126,7 @@ void cleanup_panel()
if (p->main_win)
XDestroyWindow(server.dsp, p->main_win);
p->main_win = 0;
stop_timeout(p->autohide_timeout);
}
free(panel_items_order);
@ -167,7 +168,7 @@ void init_panel()
else
nb_panel = server.nb_monitor;
panel1 = malloc(nb_panel * sizeof(Panel));
panel1 = calloc(nb_panel, sizeof(Panel));
for (i=0 ; i < nb_panel ; i++) {
memcpy(&panel1[i], &panel_config, sizeof(Panel));
}
@ -231,7 +232,7 @@ void init_panel()
}
if (panel_autohide)
add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
autohide_trigger_hide(p);
visible_taskbar(p);
}
@ -811,10 +812,7 @@ Area* click_area(Panel *panel, int x, int y)
void stop_autohide_timeout(Panel* p)
{
if (p->autohide_timeout) {
stop_timeout(p->autohide_timeout);
p->autohide_timeout = 0;
}
stop_timeout(p->autohide_timeout);
}
@ -875,10 +873,7 @@ void autohide_trigger_show(Panel* p)
{
if (!p)
return;
if (p->autohide_timeout)
change_timeout(p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
else
p->autohide_timeout = add_timeout(panel_autohide_show_timeout, 0, autohide_show, p);
change_timeout(&p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
}
@ -893,8 +888,5 @@ void autohide_trigger_hide(Panel* p)
if (XQueryPointer(server.dsp, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask))
if (child) return; // mouse over one of the system tray icons
if (p->autohide_timeout)
change_timeout(p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
else
p->autohide_timeout = add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
change_timeout(&p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
}

View file

@ -295,14 +295,14 @@ void get_monitors()
}
printf("xRandr: Found crtc's: %d\n", res->ncrtc );
server.monitor = malloc(res->ncrtc * sizeof(Monitor));
server.monitor = calloc(res->ncrtc, sizeof(Monitor));
for (i=0; i<res->ncrtc; ++i) {
XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
server.monitor[i].x = crtc_info->x;
server.monitor[i].y = crtc_info->y;
server.monitor[i].width = crtc_info->width;
server.monitor[i].height = crtc_info->height;
server.monitor[i].names = malloc((crtc_info->noutput+1) * sizeof(gchar*));
server.monitor[i].names = calloc((crtc_info->noutput+1), sizeof(gchar*));
for (j=0; j<crtc_info->noutput; ++j) {
XRROutputInfo* output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]);
printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i);
@ -315,7 +315,7 @@ void get_monitors()
nbmonitor = res->ncrtc;
}
else if (info && nbmonitor > 0) {
server.monitor = malloc(nbmonitor * sizeof(Monitor));
server.monitor = calloc(nbmonitor, sizeof(Monitor));
for (i=0 ; i < nbmonitor ; i++) {
server.monitor[i].x = info[i].x_org;
server.monitor[i].y = info[i].y_org;
@ -353,7 +353,7 @@ next:
if (!server.nb_monitor) {
server.nb_monitor = 1;
server.monitor = malloc(sizeof(Monitor));
server.monitor = calloc(1, sizeof(Monitor));
server.monitor[0].x = server.monitor[0].y = 0;
server.monitor[0].width = DisplayWidth (server.dsp, server.screen);
server.monitor[0].height = DisplayHeight (server.dsp, server.screen);

View file

@ -496,8 +496,7 @@ void remove_icon(TrayWindow *traywin)
XDestroyWindow(server.dsp, traywin->id);
XSync(server.dsp, False);
XSetErrorHandler(old);
if (traywin->render_timeout)
stop_timeout(traywin->render_timeout);
stop_timeout(traywin->render_timeout);
g_free(traywin);
// check empty systray
@ -619,8 +618,8 @@ void systray_render_icon(TrayWindow* traywin)
{
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
if (traywin->render_timeout == 0)
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin);
if (!traywin->render_timeout)
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin, &traywin->render_timeout);
}
else {
// Pixmap pix = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, server.depth);

View file

@ -87,7 +87,7 @@ Task *add_task (Window win)
if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;
tskbar = &panel1[monitor].taskbar[j];
new_tsk2 = malloc(sizeof(Task));
new_tsk2 = calloc(1, sizeof(Task));
memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area));
new_tsk2->area.parent = tskbar;
new_tsk2->win = new_tsk.win;
@ -115,7 +115,7 @@ Task *add_task (Window win)
g_ptr_array_add(task_group, new_tsk2);
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
}
Window* key = malloc(sizeof(Window));
Window* key = calloc(1, sizeof(Window));
*key = new_tsk.win;
g_hash_table_insert(win_to_task_table, key, task_group);
set_task_state(new_tsk2, new_tsk.current_state);
@ -195,14 +195,14 @@ int get_title(Task *tsk)
if (!name || !strlen(name)) {
name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0);
if (!name || !strlen(name)) {
name = malloc(10);
name = calloc(10, 1);
strcpy(name, "Untitled");
}
}
}
// add space before title
title = malloc(strlen(name)+2);
title = calloc(strlen(name)+2, 1);
if (panel->g_task.icon) strcpy(title, " ");
else title[0] = 0;
strcat(title, name);
@ -620,7 +620,7 @@ void add_urgent(Task *tsk)
urgent_list = g_slist_prepend(urgent_list, tsk);
if (!urgent_timeout)
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0);
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0, &urgent_timeout);
Panel *panel = tsk->area.panel;
if (panel->is_hidden)

View file

@ -109,7 +109,6 @@ void cleanup_taskbar()
urgent_list = NULL;
stop_timeout(urgent_timeout);
urgent_timeout = NULL;
}

View file

@ -1350,7 +1350,7 @@ start:
cmd_length += 2; // &)
cmd_length += 1; // terminator
char *cmd = malloc(cmd_length);
char *cmd = calloc(cmd_length, 1);
cmd[0] = '\0';
strcat(cmd, "(");
strcat(cmd, dnd_launcher_exec);

View file

@ -86,7 +86,7 @@ void init_tooltip()
void tooltip_trigger_show(Area* area, Panel* p, XEvent *e)
{
// Position the tooltip in the center of the area
x = area->posx + area->width / 2 + e->xmotion.x_root - e->xmotion.x;
x = area->posx + MIN(area->width / 3, 22) + e->xmotion.x_root - e->xmotion.x;
y = area->posy + area->height / 2 + e->xmotion.y_root - e->xmotion.y;
just_shown = 1;
g_tooltip.panel = p;
@ -108,7 +108,6 @@ void tooltip_show(void* arg)
XTranslateCoordinates( server.dsp, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
Area* area;
area = click_area(g_tooltip.panel, mx, my);
stop_tooltip_timeout();
if (!g_tooltip.mapped && area->_get_tooltip_text) {
tooltip_copy_text(area);
g_tooltip.mapped = True;
@ -275,7 +274,6 @@ void tooltip_trigger_hide(Tooltip* tooltip)
void tooltip_hide(void* arg)
{
stop_tooltip_timeout();
if (g_tooltip.mapped) {
g_tooltip.mapped = False;
XUnmapWindow(server.dsp, g_tooltip.window);
@ -286,26 +284,19 @@ void tooltip_hide(void* arg)
void start_show_timeout()
{
if (g_tooltip.timeout)
change_timeout(g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
else
g_tooltip.timeout = add_timeout(g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
}
void start_hide_timeout()
{
if (g_tooltip.timeout)
change_timeout(g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
else
g_tooltip.timeout = add_timeout(g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
}
void stop_tooltip_timeout()
{
stop_timeout(g_tooltip.timeout);
g_tooltip.timeout = NULL;
}

View file

@ -44,6 +44,7 @@ struct _timeout {
void (*_callback)(void*);
void* arg;
multi_timeout* multi_timeout;
timeout **self;
};
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
@ -74,6 +75,8 @@ void cleanup_timeout()
timeout* t = timeout_list->data;
if (t->multi_timeout)
stop_multi_timeout(t);
if (t->self)
*t->self = NULL;
free(t);
timeout_list = g_slist_remove(timeout_list, t);
}
@ -95,25 +98,26 @@ void cleanup_timeout()
* however it's save to call it.
**/
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg)
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self)
{
timeout* t = malloc(sizeof(timeout));
t->multi_timeout = 0;
timeout* t = calloc(1, sizeof(timeout));
t->self = self;
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
return t;
}
void change_timeout(timeout *t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
{
if ( g_slist_find(timeout_list, t) == 0 && g_hash_table_lookup(multi_timeouts, t) == 0)
printf("programming error: timeout already deleted...");
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
*t = add_timeout(value_msec, interval_msec, _callback, arg, t);
else {
if (t->multi_timeout)
remove_from_multi_timeout((timeout*)t);
if ((*t)->multi_timeout)
remove_from_multi_timeout(*t);
else
timeout_list = g_slist_remove(timeout_list, t);
add_timeout_intern(value_msec, interval_msec, _callback, arg, (timeout*)t);
timeout_list = g_slist_remove(timeout_list, *t);
add_timeout_intern(value_msec, interval_msec, _callback, arg, *t);
}
}
@ -149,31 +153,40 @@ void callback_timeout_expired()
if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) {
// it's time for the callback function
t->_callback(t->arg);
// If _callback() calls stop_timeout(t) the timer 't' was freed and is not in the timeout_list
if (g_slist_find(timeout_list, t)) {
// if _callback() calls stop_timeout(t) the timeout 't' was freed and is not in the timeout_list
// Timer still exists
timeout_list = g_slist_remove(timeout_list, t);
if (t->interval_msec > 0)
if (t->interval_msec > 0) {
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t);
else
} else {
// Destroy single-shot timer
if (t->self)
*t->self = NULL;
free(t);
}
}
}
else
} else {
return;
}
}
}
void stop_timeout(timeout* t)
{
if (!multi_timeouts || !t)
if (!t)
return;
// if not in the list, it was deleted in callback_timeout_expired
if (g_slist_find(timeout_list, t) || g_hash_table_lookup(multi_timeouts, t)) {
if (t->multi_timeout)
remove_from_multi_timeout((timeout*)t);
timeout_list = g_slist_remove(timeout_list, t);
free((void*)t);
if ((timeout_list && g_slist_find(timeout_list, t)) ||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
if (multi_timeouts && t->multi_timeout)
remove_from_multi_timeout(t);
if (timeout_list)
timeout_list = g_slist_remove(timeout_list, t);
if (t->self)
*t->self = NULL;
free(t);
}
}
@ -198,7 +211,7 @@ void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), v
gint compare_timeouts(gconstpointer t1, gconstpointer t2)
{
return compare_timespecs(&((timeout*)t1)->timeout_expires,
&((timeout*)t2)->timeout_expires);
&((timeout*)t2)->timeout_expires);
}
@ -262,12 +275,13 @@ int align_with_existing_timeouts(timeout *t)
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
if (multi_timeouts == 0)
multi_timeouts = g_hash_table_new(0, 0);
if (!t->multi_timeout && !t2->multi_timeout)
if (!t->multi_timeout && !t2->multi_timeout) {
// both timeouts can be aligned, but there is no multi timeout for them
create_multi_timeout(t, t2);
else
} else {
// there is already a multi timeout, so we append the new timeout to the multi timeout
append_multi_timeout(t, t2);
}
return 1;
}
}
@ -295,10 +309,10 @@ int calc_multi_timeout_interval(multi_timeout_handler* mth)
void create_multi_timeout(timeout* t1, timeout* t2)
{
multi_timeout* mt1 = malloc(sizeof(multi_timeout));
multi_timeout* mt2 = malloc(sizeof(multi_timeout));
multi_timeout_handler* mth = malloc(sizeof(multi_timeout_handler));
timeout* real_timeout = malloc(sizeof(timeout));
multi_timeout* mt1 = calloc(1, sizeof(multi_timeout));
multi_timeout* mt2 = calloc(1, sizeof(multi_timeout));
multi_timeout_handler* mth = calloc(1, sizeof(multi_timeout_handler));
timeout* real_timeout = calloc(1, sizeof(timeout));
mth->timeout_list = 0;
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
@ -331,7 +345,7 @@ void append_multi_timeout(timeout* t1, timeout* t2)
t1 = tmp;
}
multi_timeout* mt = malloc(sizeof(multi_timeout));
multi_timeout* mt = calloc(1, sizeof(multi_timeout));
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t1);
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);

View file

@ -21,7 +21,6 @@
#include <glib.h>
extern GSList* timeout_list;
extern struct timeval next_timeout;
@ -30,26 +29,33 @@ typedef struct _timeout timeout;
// timer functions
/**
* Single shot timer (i.e. timer with interval_msec == 0) are deleted automatically as soon as they expire
* Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
* i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
* You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
* case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
* to be either valid or NULL.
* Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
* integral multiple of the other.
**/
/** default global data **/
/** Initializes default global data. **/
void default_timeout();
/** freed memory : stops all timeouts **/
/** Cleans up: stops all timers and frees memory. **/
void cleanup_timeout();
/** installs a timeout with the first timeout of 'value_msec' and then a periodic timeout with
* 'interval_msec'. '_callback' is the callback function when the timer reaches the timeout.
* returns a pointer to the timeout, which is needed for stopping it again
/** Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
* 'interval_msec' (set it to 0 to prevent periodic timeouts).
* '_callback' is the function called when the timer reaches the timeout.
* 'arg' is the argument passed to the callback function.
* 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
* is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
* Returns a pointer to the timer, which is needed for stopping/changing it.
**/
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self);
/** changes timeout 't'. If timeout 't' does not exist, nothing happens **/
void change_timeout(timeout* t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
/** Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'. **/
void change_timeout(timeout** t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
/** stops the timeout 't' **/
void stop_timeout(timeout* t);