aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/basetypes/MCMainThreadGTK.cpp
blob: 13396a52619214e836d4836b1e0c4a6b11812dee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//
//  MCMainThreadGTK.cpp
//  mailcore2
//
//  Created by Hoa Dinh on 11/11/14.
//  Copyright (c) 2014 MailCore. All rights reserved.
//

#include "MCMainThread.h"

#include <glib.h>
#include <stdlib.h>
#include <libetpan/libetpan.h>

struct main_thread_call_data {
  void (* function)(void *);
  void * context;
  struct mailsem * sem;
};

static gboolean main_thread_wrapper(struct main_thread_call_data * data)
{
  data->function(data->context);
  free(data);
  return G_SOURCE_REMOVE;
}

void mailcore::callOnMainThread(void (* function)(void *), void * context)
{
  struct main_thread_call_data * data = (struct main_thread_call_data *) malloc(sizeof(* data));
  data->function = function;
  data->context = context;
  data->sem = NULL;
  g_idle_add((GSourceFunc) main_thread_wrapper, (gpointer) data);
}

static gboolean main_thread_wait_wrapper(struct main_thread_call_data * data)
{
  data->function(data->context);
  mailsem_up(data->sem);
  return G_SOURCE_REMOVE;
}

void mailcore::callOnMainThreadAndWait(void (* function)(void *), void * context)
{
  struct main_thread_call_data * data = (struct main_thread_call_data *) malloc(sizeof(* data));
  data->function = function;
  data->context = context;
  data->sem = mailsem_new();
  g_idle_add((GSourceFunc) main_thread_wait_wrapper, (gpointer) data);
  
  // Wait.
  mailsem_down(data->sem);
  
  mailsem_free(data->sem);
  free(data);
}

struct call_after_delay_data {
  void (* function)(void *);
  void * context;
  guint source_id;
};

static gboolean call_after_delay_wrapper(struct main_thread_call_data * data)
{
  data->function(data->context);
  free(data);
  return G_SOURCE_REMOVE;
}

static void call_after_delay_destroy_notify(struct main_thread_call_data * data)
{
  // Do nothing.
}

void * mailcore::callAfterDelay(void (* function)(void *), void * context, double time)
{
  struct call_after_delay_data * data = (struct call_after_delay_data *) malloc(sizeof(* data));
  data->function = function;
  data->context = context;
  data->source_id = g_timeout_add_full(G_PRIORITY_DEFAULT, (guint) (time * 1000),
                      (GSourceFunc) call_after_delay_wrapper, data,
                      (GDestroyNotify) call_after_delay_destroy_notify);
  return data;
}

void mailcore::cancelDelayedCall(void * delayedCall)
{
  struct call_after_delay_data * data = (struct call_after_delay_data *) delayedCall;
  g_source_remove(data->source_id);
  free(data);
}