/** * This function is called every 5 minutes by the GLib main loop, and * saves the state file. */ static gboolean timer_save_state_file(G_GNUC_UNUSED gpointer data) { if (prev_volume_version == sw_volume_state_get_hash() && prev_output_version == audio_output_state_get_version() && prev_playlist_version == playlist_state_get_hash(&g_playlist)) /* nothing has changed - don't save the state file, don't spin up the hard disk */ return true; state_file_write(); return true; }
void state_file_finish(void) { if (state_file_path == NULL) /* no state file configured, no cleanup required */ return; if (save_state_source_id != 0) g_source_remove(save_state_source_id); state_file_write(); g_free(state_file_path); }
/** * This function is called every 5 minutes by the GLib main loop, and * saves the state file. */ static gboolean timer_save_state_file(gpointer data) { struct player_control *pc = data; if (prev_volume_version == sw_volume_state_get_hash() && prev_output_version == audio_output_state_get_version() && prev_playlist_version == playlist_state_get_hash(&g_playlist, pc)) /* nothing has changed - don't save the state file, don't spin up the hard disk */ return true; state_file_write(pc); return true; }
void event_process(void) { Event *event; AtCommand *at; SList *list, *prev_link = NULL, *next_link, *expired_link, tmp_link; int minute_tick, five_minute_tick, ten_minute_tick, fifteen_minute_tick, thirty_minute_tick, hour_tick, day_tick; struct tm *tm_now; static struct tm tm_prev; static time_t t_prev; time(&pikrellcam.t_now); pikrellcam.second_tick = (pikrellcam.t_now == t_prev) ? FALSE : TRUE; t_prev = pikrellcam.t_now; if (pikrellcam.second_tick) { tm_prev = pikrellcam.tm_local; tm_now = localtime(&pikrellcam.t_now); minute_tick = (tm_now->tm_min != tm_prev.tm_min) ? TRUE : FALSE; pikrellcam.tm_local = *tm_now; } else minute_tick = FALSE; if (pikrellcam.state_modified || minute_tick) { pikrellcam.state_modified = FALSE; state_file_write(); } tmp_link.next = NULL; for (list = event_list; list; prev_link = list, list = list->next) { /* Event loop processing is done with the list unlocked until we | have an expired link that must be removed from the list so that | called event functions cad add events to the list. | If another thread adds an event, only the last list->next | will be modified and this loop will catch it or it won't. */ event = (Event *) list->data; if ( (event->time == 0 && event->count == 0) || event->func == NULL ) /* not activated */ continue; if (event->time > 0 && event->time > pikrellcam.t_now) continue; else if (event->count > 0 && --event->count > 0) continue; if (pikrellcam.verbose) printf("Event func -> [%s] period=%d\n", event->name, (int) event->period); if (event->func) (*event->func)(event->data); if (event->period > 0) event->time += event->period; else { pthread_mutex_lock(&event_mutex); expired_link = list; if (list == event_list) { event_list = list->next; tmp_link.next = list->next; list = &tmp_link; } else { next_link = list->next; list = prev_link; list->next = next_link; } free(expired_link->data); free(expired_link); pthread_mutex_unlock(&event_mutex); } } if (minute_tick) { char *p, buf[IBUF_LEN]; int i, n, minute_now, minute_at, minute_offset = 0; static int start = TRUE; static int at_notify_fd, at_notify_wd; struct inotify_event *event; if (at_notify_fd == 0) { at_notify_fd = inotify_init(); if (at_notify_fd > 0) { fcntl(at_notify_fd, F_SETFL, fcntl(at_notify_fd, F_GETFL) | O_NONBLOCK); at_notify_wd = inotify_add_watch(at_notify_fd, pikrellcam.config_dir, IN_CREATE | IN_MODIFY); } } else if (at_notify_wd > 0) { n = read(at_notify_fd, buf, IBUF_LEN); if (n > 0) { for (i = 0; i < n; i += sizeof(*event) + event->len) { event = (struct inotify_event *) &buf[i]; if ( event->len > 0 && !strcmp(event->name, PIKRELLCAM_AT_COMMANDS_CONFIG) ) at_commands_config_load(pikrellcam.at_commands_config_file); } } } tm_now = &pikrellcam.tm_local; minute_now = tm_now->tm_hour * 60 + tm_now->tm_min; five_minute_tick = ((tm_now->tm_min % 5) == 0) ? TRUE : FALSE; ten_minute_tick = ((tm_now->tm_min % 10) == 0) ? TRUE : FALSE; fifteen_minute_tick = ((tm_now->tm_min % 15) == 0) ? TRUE : FALSE; thirty_minute_tick = ((tm_now->tm_min % 10) == 0) ? TRUE : FALSE; hour_tick = (tm_now->tm_hour != tm_prev.tm_hour) ? TRUE : FALSE; day_tick = (tm_now->tm_mday != tm_prev.tm_mday) ? TRUE : FALSE; if (day_tick || !sun.initialized) { if (sun.initialized) { char tbuf[32]; log_printf_no_timestamp("\n========================================================\n"); strftime(tbuf, sizeof(tbuf), "%F", localtime(&pikrellcam.t_now)); log_printf_no_timestamp("%s ================== New Day ==================\n", tbuf); log_printf_no_timestamp("========================================================\n"); strftime(tbuf, sizeof(tbuf), "%F", localtime(&pikrellcam.t_now)); } sun_times_init(); sun.initialized = TRUE; log_lines(); state_file_write(); } for (list = at_command_list; list; list = list->next) { at = (AtCommand *) list->data; if ((p = strchr(at->at_time, '+')) != NULL) minute_offset = atoi(p + 1); else if ((p = strchr(at->at_time, '-')) != NULL) minute_offset = -atoi(p + 1); if (!strcmp(at->at_time, "start")) minute_at = start ? minute_now : 0; else if (!strcmp(at->at_time, "minute")) minute_at = minute_now; else if (!strcmp(at->at_time, "5minute")) minute_at = five_minute_tick ? minute_now : 0; else if (!strcmp(at->at_time, "10minute")) minute_at = ten_minute_tick ? minute_now : 0; else if (!strcmp(at->at_time, "15minute")) minute_at = fifteen_minute_tick ? minute_now : 0; else if (!strcmp(at->at_time, "30minute")) minute_at = thirty_minute_tick ? minute_now : 0; else if (!strcmp(at->at_time, "hour")) minute_at = hour_tick ? minute_now : 0; else if (!strncmp(at->at_time, "dawn", 4)) minute_at = sun.dawn + minute_offset; else if (!strncmp(at->at_time, "dusk", 4)) minute_at = sun.dusk + minute_offset; else if (!strncmp(at->at_time, "sunrise", 7)) minute_at = sun.sunrise + minute_offset; else if (!strncmp(at->at_time, "sunset", 6)) minute_at = sun.sunset + minute_offset; else if (!strncmp(at->at_time, "nautical_dawn", 13)) minute_at = sun.nautical_dawn + minute_offset; else if (!strncmp(at->at_time, "nautical_dusk", 13)) minute_at = sun.nautical_dusk + minute_offset; else { minute_at = (int) strtol(at->at_time, &p, 10) * 60; if (*p == ':') minute_at += strtol(p + 1, NULL, 10); else { minute_at = 0; /* error in at_time string */ log_printf("Error in at_command: [%s] bad at_time: [%s]\n", at->command, at->at_time); } } if (minute_now != minute_at) continue; /* Have a time match so check frequency. */ if ( !strcmp(at->frequency, "daily") || ( !strcmp(at->frequency, "Sat-Sun") && (tm_now->tm_wday == 0 || tm_now->tm_wday == 6) ) || ( !strcmp(at->frequency, "Mon-Fri") && tm_now->tm_wday > 0 && tm_now->tm_wday < 6 ) || ( (p = strstr(weekdays, at->frequency)) != NULL && (p - weekdays) / 3 == tm_now->tm_wday ) ) { if (*(at->command) == '@') command_process(at->command + 1); else exec_no_wait(at->command, NULL); } } start = FALSE; if (pikrellcam.config_modified) config_save(pikrellcam.config_file); } }