diff --git a/sample/tint2rc b/sample/tint2rc index 0e153e8..03b0839 100644 --- a/sample/tint2rc +++ b/sample/tint2rc @@ -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 diff --git a/src/battery/battery.c b/src/battery/battery.c index bcac447..caf7630 100644 --- a/src/battery/battery.c +++ b/src/battery/battery.c @@ -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); } diff --git a/src/clock/clock.c b/src/clock/clock.c index 6938414..1592ea2 100644 --- a/src/clock/clock.c +++ b/src/clock/clock.c @@ -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); } } } diff --git a/src/launcher/apps-common.c b/src/launcher/apps-common.c index 6508e14..2d3ef5b 100644 --- a/src/launcher/apps-common.c +++ b/src/launcher/apps-common.c @@ -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++) { diff --git a/src/launcher/icon-theme-common.c b/src/launcher/icon-theme-common.c index f44eaee..17dc16c 100644 --- a/src/launcher/icon-theme-common.c +++ b/src/launcher/icon-theme-common.c @@ -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) diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index 796aa07..e91ed69 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -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; diff --git a/src/launcher/xsettings-client.c b/src/launcher/xsettings-client.c index 23c0efa..00e83da 100644 --- a/src/launcher/xsettings-client.c +++ b/src/launcher/xsettings-client.c @@ -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; diff --git a/src/launcher/xsettings-common.c b/src/launcher/xsettings-common.c index 9fe5011..c7637e4 100644 --- a/src/launcher/xsettings-common.c +++ b/src/launcher/xsettings-common.c @@ -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; diff --git a/src/panel.c b/src/panel.c index f104546..6b2e5e8 100644 --- a/src/panel.c +++ b/src/panel.c @@ -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); } diff --git a/src/server.c b/src/server.c index 0610ed4..44c570b 100644 --- a/src/server.c +++ b/src/server.c @@ -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; incrtc; ++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; jnoutput; ++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); diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 15806b8..7034670 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -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); diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 60c0632..62303b2 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -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) diff --git a/src/taskbar/taskbar.c b/src/taskbar/taskbar.c index 33aa864..5b0f510 100644 --- a/src/taskbar/taskbar.c +++ b/src/taskbar/taskbar.c @@ -109,7 +109,6 @@ void cleanup_taskbar() urgent_list = NULL; stop_timeout(urgent_timeout); - urgent_timeout = NULL; } diff --git a/src/tint.c b/src/tint.c index 3593258..607692f 100644 --- a/src/tint.c +++ b/src/tint.c @@ -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); diff --git a/src/tooltip/tooltip.c b/src/tooltip/tooltip.c index 66bc29b..294c837 100644 --- a/src/tooltip/tooltip.c +++ b/src/tooltip/tooltip.c @@ -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; } diff --git a/src/util/timer.c b/src/util/timer.c index 8b0cb5d..65f5b85 100644 --- a/src/util/timer.c +++ b/src/util/timer.c @@ -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); diff --git a/src/util/timer.h b/src/util/timer.h index 250e7e0..6411b2f 100644 --- a/src/util/timer.h +++ b/src/util/timer.h @@ -21,7 +21,6 @@ #include -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);