tpl_gsource_functions *gsource_funcs;
tpl_gsource_type_t type;
+ tpl_gsource *finalizer;
void *data;
};
thread->func = NULL;
free(thread);
+ thread = NULL;
}
static gboolean
tpl_gsource *gsource = (tpl_gsource *)source;
tpl_bool_t ret = TPL_FALSE;
- if (gsource->gsource_funcs->prepare)
+ if (gsource->type != SOURCE_TYPE_NORMAL)
+ return ret;
+
+ if (gsource->gsource_funcs && gsource->gsource_funcs->prepare)
ret = gsource->gsource_funcs->prepare(gsource);
*time = -1;
tpl_gsource *gsource = (tpl_gsource *)source;
tpl_bool_t ret = TPL_FALSE;
- if (gsource->gsource_funcs->check)
+ if (gsource->type != SOURCE_TYPE_NORMAL)
+ return ret;
+
+ if (gsource->gsource_funcs && gsource->gsource_funcs->check)
ret = gsource->gsource_funcs->check(gsource);
return ret;
GIOCondition cond = g_source_query_unix_fd(source, gsource->tag);
TPL_IGNORE(cb);
- TPL_IGNORE(data);
if (cond & G_IO_IN) {
- if (gsource->gsource_funcs->dispatch)
+ if (gsource->gsource_funcs && gsource->gsource_funcs->dispatch)
ret = gsource->gsource_funcs->dispatch(gsource);
+
+ if (gsource->type == SOURCE_TYPE_FINALIZER) {
+ tpl_gsource *del_source = (tpl_gsource *)data;
+ if (!g_source_is_destroyed(&del_source->gsource)) {
+ g_mutex_lock(&del_source->thread->thread_mutex);
+
+ g_source_remove_unix_fd(&del_source->gsource, del_source->tag);
+ g_source_destroy(&del_source->gsource);
+ g_source_unref(&del_source->gsource);
+
+ g_cond_signal(&del_source->thread->thread_cond);
+ g_mutex_unlock(&del_source->thread_mutex);
+ }
+ }
} else {
/* When some io errors occur, it is not considered as a critical error.
* There may be problems with the screen, but it does not affect the operation. */
gsource, gsource->fd, cond);
}
- if (gsource->type == SOURCE_TYPE_DISPOSABLE)
+ if (gsource->type == SOURCE_TYPE_DISPOSABLE ||
+ gsource->type == SOURCE_TYPE_FINALIZER) {
+ g_source_remove_unix_fd(&gsource->gsource, gsource->tag);
+ g_source_destroy(&gsource->gsource);
+ g_source_unref(&gsource->gsource);
ret = TPL_GSOURCE_REMOVE;
+ }
return ret;
}
{
tpl_gsource *gsource = (tpl_gsource *)source;
- if (gsource->gsource_funcs->finalize)
+ if (gsource->gsource_funcs && gsource->gsource_funcs->finalize)
gsource->gsource_funcs->finalize(gsource);
if (gsource->is_eventfd)
gsource->thread = NULL;
gsource->gsource_funcs = NULL;
gsource->data = NULL;
+ gsource->finalizer = NULL;
}
static GSourceFuncs _thread_source_funcs = {
new_gsource->data = data;
new_gsource->type = type;
+ if (new_gsource->type == SOURCE_TYPE_NORMAL) {
+ tpl_gsource *finalizer = tpl_gsource_create(thread, new_gsource, -1,
+ NULL, SOURCE_TYPE_FINALIZER);
+ new_gsource->finalizer = finalizer;
+ } else
+ new_gsource->finalizer = NULL;
+
new_gsource->tag = g_source_add_unix_fd(&new_gsource->gsource,
new_gsource->fd,
G_IO_IN | G_IO_ERR);
void
tpl_gsource_destroy(tpl_gsource *source)
{
- g_source_remove_unix_fd(&source->gsource, source->tag);
- g_source_destroy(&source->gsource);
- g_source_unref(&source->gsource);
+ if (g_source_is_destroyed(&source->gsource)) {
+ TPL_WARN("gsource(%p) already has been destroyed.",
+ source);
+ return;
+ }
+
+ if (source->type == SOURCE_TYPE_NORMAL &&
+ source->finalizer != NULL) {
+ g_mutex_lock(&source->thread->thread_mutex);
+
+ tpl_gsource_send_event(source->finalizer, 1);
+
+ g_cond_wait(&source->thread->thread_cond, &source->thread->thread_mutex);
+ g_mutex_unlock(&source->thread->thread_mutex);
+ }
+
+
+ if (!g_source_is_destroyed(&source->gsource) &&
+ !(source->type == SOURCE_TYPE_DISPOSABLE ||
+ source->type == SOURCE_TYPE_FINALIZER)) {
+ g_source_remove_unix_fd(&source->gsource, source->tag);
+ g_source_destroy(&source->gsource);
+ g_source_unref(&source->gsource);
+ }
}
void
uint64_t value = message;
int ret;
- ret = write(del_source->event_fd, &value, sizeof(uint64_t));
+ ret = write(source->event_fd, &value, sizeof(uint64_t));
if (ret == -1) {
TPL_ERR("failed to send devent. tpl_gsource(%p)",
source);