/* for SW */
tdm_event_loop_source *SW_timer;
struct list_head SW_wait_list;
+
+ /* for timeout */
+ tdm_event_loop_source *timeout_timer;
} tdm_private_vblank;
struct _tdm_vblank_wait_info {
static void _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence,
unsigned int tv_sec, unsigned int tv_usec,
void *user_data);
+static void _tdm_vblank_timeout_timer_update(tdm_private_vblank *private_vblank, int ms_delay);
+static void _tdm_vblank_get_client_information(tdm_private_vblank *private_vblank,
+ pid_t *pid, const char **name);
#if 0
static void
{
tdm_vblank_wait_info *w = NULL, *ww = NULL;
+ if (!LIST_IS_EMPTY(&private_vblank->SW_wait_list))
+ TDM_NEVER_GET_HERE();
+
+ tdm_display_lock(private_vblank->dpy);
+ _tdm_vblank_timeout_timer_update(private_vblank, 0);
+ tdm_display_unlock(private_vblank->dpy);
+
LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) {
LIST_DEL(&w->link);
_tdm_vblank_valid_list_del(&w->valid_link);
tdm_output_remove_change_handler(private_vblank->output,
_tdm_vblank_cb_output_change, private_vblank);
- _tdm_vblank_free_HW_wait(private_vblank, 0, 0);
-
LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) {
LIST_DEL(&w->link);
_tdm_vblank_valid_list_del(&w->valid_link);
free(w);
}
+ _tdm_vblank_free_HW_wait(private_vblank, 0, 0);
+
+ if (private_vblank->timeout_timer) {
+ tdm_display_lock(private_vblank->dpy);
+ tdm_event_loop_source_remove(private_vblank->timeout_timer);
+ tdm_display_unlock(private_vblank->dpy);
+ }
+
VIN("destroyed");
free(private_vblank);
}
static tdm_error
+_tdm_vblank_timeout_timer_cb(void *user_data)
+{
+ tdm_private_vblank *private_vblank = user_data;
+ tdm_vblank_wait_info *w = NULL, *ww = NULL;
+ tdm_error error = TDM_ERROR_TIMEOUT;
+ pid_t pid;
+ const char *proc_name;
+
+ TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_OPERATION_FAILED);
+
+ _tdm_vblank_get_client_information(private_vblank, &pid, &proc_name);
+
+ if (!LIST_IS_EMPTY(&private_vblank->HW_wait_list)) {
+
+ VER("HW vblank TIMEOUT!! (pid: %u, name: %s)", pid, proc_name);
+
+ LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) {
+ LIST_DEL(&w->link);
+ _tdm_vblank_valid_list_del(&w->valid_link);
+
+ tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, w);
+
+ if (w->func)
+ w->func(private_vblank, error, 0, 0, 0, w->user_data);
+
+ free(w);
+ }
+ }
+
+ if (!LIST_IS_EMPTY(&private_vblank->SW_wait_list)) {
+
+ VER("SW vblank TIMEOUT!! (pid: %u, name: %s)", pid, proc_name);
+
+ LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->SW_wait_list, link) {
+ LIST_DEL(&w->link);
+ _tdm_vblank_valid_list_del(&w->valid_link);
+
+ if (w->func)
+ w->func(private_vblank, error, 0, 0, 0, w->user_data);
+
+ free(w);
+ }
+ }
+
+ return TDM_ERROR_NONE;
+}
+
+static void
+_tdm_vblank_timeout_timer_update(tdm_private_vblank *private_vblank, int ms_delay)
+{
+ tdm_error ret;
+
+ if (!private_vblank->timeout_timer) {
+ private_vblank->timeout_timer =
+ tdm_event_loop_add_timer_handler(private_vblank->dpy,
+ _tdm_vblank_timeout_timer_cb,
+ private_vblank,
+ &ret);
+ if (!private_vblank->timeout_timer) {
+ VER("couldn't add timer");
+ return;
+ }
+ VIN("Create Timeout timer");
+ }
+
+ ret = tdm_event_loop_source_timer_update(private_vblank->timeout_timer, ms_delay);
+ if (ret != TDM_ERROR_NONE) {
+ VER("couldn't update timer");
+ return;
+ }
+
+ if (ms_delay != 0)
+ VDB("timeout timer updated");
+ else
+ VDB("timeout timer disabled");
+}
+
+static tdm_error
_tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank)
{
tdm_vblank_wait_info *first_wait_info = NULL;
VWR("couldn't update sw timer");
}
+ if (!LIST_IS_EMPTY(&private_vblank->SW_wait_list))
+ TDM_NEVER_GET_HERE();
+
+ tdm_display_lock(private_vblank->dpy);
+ _tdm_vblank_timeout_timer_update(private_vblank, 0);
+ tdm_display_unlock(private_vblank->dpy);
+
LIST_DEL(&wait_info->link);
_tdm_vblank_valid_list_del(&wait_info->valid_link);
return TDM_ERROR_OPERATION_FAILED;
}
+ if (!LIST_IS_EMPTY(&private_vblank->HW_wait_list))
+ TDM_NEVER_GET_HERE();
+
+ _tdm_vblank_timeout_timer_update(private_vblank, 0);
+
first_wait_info = container_of(private_vblank->SW_wait_list.next, first_wait_info, link);
TDM_RETURN_VAL_IF_FAIL(first_wait_info != NULL, TDM_ERROR_OPERATION_FAILED);
return ret;
}
+ tdm_display_lock(private_vblank->dpy);
+ _tdm_vblank_timeout_timer_update(private_vblank, 2000);
+ tdm_display_unlock(private_vblank->dpy);
+
return TDM_ERROR_NONE;
}
return private_vblank->stamp;
}
+static void
+_tdm_vblank_get_client_information(tdm_private_vblank *private_vblank, pid_t *pid, const char **name)
+{
+ struct wl_client *client;
+
+ if (!private_vblank->resource)
+ goto no_client;
+
+ client = wl_resource_get_client(private_vblank->resource);
+ if (!client)
+ goto no_client;
+
+ wl_client_get_credentials(client, pid, NULL, NULL);
+ *name = tdm_server_get_client_name(*pid);
+
+ return;
+
+no_client:
+ *pid = 0;
+ *name = NULL;
+ return;
+}
+
INTERN void
tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len)
{
const char *proc_name = NULL;
pid_t pid = 0;
- if (v->resource) {
- struct wl_client *client = wl_resource_get_client(v->resource);
- if (client) {
- wl_client_get_credentials(client, &pid, NULL, NULL);
- proc_name = tdm_server_get_client_name(pid);
- }
- }
+ _tdm_vblank_get_client_information(v, &pid, &proc_name);
TDM_SNPRINTF(reply, len, "%-12s %u %u %d %u %s (pid: %u)\n",
v->name, v->fps, v->ignore_global_fps, v->offset, v->enable_fake,