~ubuntu-branches/ubuntu/wily/evolution-data-server/wily

« back to all changes in this revision

Viewing changes to camel/camel-async-closure.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2015-07-20 13:34:59 UTC
  • mfrom: (1.1.126) (1.2.48 sid)
  • Revision ID: package-import@ubuntu.com-20150720133459-g6y46hnu5ewtoz08
Tags: 3.16.4-0ubuntu2
debian/patches/0001-Bug-752373-Monthly-events-do-not-recur-correctly.patch:
Cherry-pick patch from upstream to fix events not recurring correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * camel-async-closure.c
3
3
 *
4
 
 * This library is free software you can redistribute it and/or modify it
 
4
 * This library is free software: you can redistribute it and/or modify it
5
5
 * under the terms of the GNU Lesser General Public License as published by
6
6
 * the Free Software Foundation.
7
7
 *
8
8
 * This library is distributed in the hope that it will be useful, but
9
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
10
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
11
 * for more details.
12
12
 *
13
13
 * You should have received a copy of the GNU Lesser General Public License
14
 
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 
14
 * along with this library. If not, see <http://www.gnu.org/licenses/>.
15
15
 *
16
16
 */
17
17
 
54
54
        GMainLoop *loop;
55
55
        GMainContext *context;
56
56
        GAsyncResult *result;
 
57
        gboolean finished;
 
58
        GMutex lock;
57
59
};
58
60
 
59
61
/**
73
75
        closure = g_slice_new0 (CamelAsyncClosure);
74
76
        closure->context = g_main_context_new ();
75
77
        closure->loop = g_main_loop_new (closure->context, FALSE);
 
78
        closure->finished = FALSE;
 
79
        g_mutex_init (&closure->lock);
76
80
 
77
81
        g_main_context_push_thread_default (closure->context);
78
82
 
79
83
        return closure;
80
84
}
81
85
 
 
86
static gboolean
 
87
camel_async_closure_unlock_mutex_cb (gpointer user_data)
 
88
{
 
89
        CamelAsyncClosure *closure = user_data;
 
90
 
 
91
        g_return_val_if_fail (closure != NULL, FALSE);
 
92
 
 
93
        g_mutex_unlock (&closure->lock);
 
94
 
 
95
        return FALSE;
 
96
}
 
97
 
82
98
/**
83
99
 * camel_async_closure_wait:
84
100
 * @closure: a #CamelAsyncClosure
99
115
{
100
116
        g_return_val_if_fail (closure != NULL, NULL);
101
117
 
102
 
        g_main_loop_run (closure->loop);
 
118
        g_mutex_lock (&closure->lock);
 
119
        if (closure->finished) {
 
120
                g_mutex_unlock (&closure->lock);
 
121
        } else {
 
122
                GSource *idle_source;
 
123
 
 
124
                /* Unlock the closure->lock in the main loop, to ensure thread safety.
 
125
                   It should be processed before anything else, otherwise deadlock happens. */
 
126
                idle_source = g_idle_source_new ();
 
127
                g_source_set_callback (idle_source, camel_async_closure_unlock_mutex_cb, closure, NULL);
 
128
                g_source_set_priority (idle_source, G_PRIORITY_HIGH * 2);
 
129
                g_source_attach (idle_source, closure->context);
 
130
                g_source_unref (idle_source);
 
131
 
 
132
                g_main_loop_run (closure->loop);
 
133
        }
103
134
 
104
135
        return closure->result;
105
136
}
122
153
        g_main_loop_unref (closure->loop);
123
154
        g_main_context_unref (closure->context);
124
155
 
125
 
        if (closure->result != NULL)
126
 
                g_object_unref (closure->result);
 
156
        g_mutex_lock (&closure->lock);
 
157
        g_clear_object (&closure->result);
 
158
        g_mutex_unlock (&closure->lock);
 
159
        g_mutex_clear (&closure->lock);
127
160
 
128
161
        g_slice_free (CamelAsyncClosure, closure);
129
162
}
153
186
 
154
187
        real_closure = closure;
155
188
 
 
189
        g_mutex_lock (&real_closure->lock);
 
190
 
156
191
        /* Replace any previous result. */
157
192
        if (real_closure->result != NULL)
158
193
                g_object_unref (real_closure->result);
159
194
        real_closure->result = g_object_ref (result);
 
195
        real_closure->finished = TRUE;
 
196
 
 
197
        g_mutex_unlock (&real_closure->lock);
160
198
 
161
199
        g_main_loop_quit (real_closure->loop);
162
200
}