| | 126 | |
|---|
| | 127 | return; |
|---|
| | 128 | } |
|---|
| | 129 | |
|---|
| | 130 | |
|---|
| | 131 | |
|---|
| | 132 | |
|---|
| | 133 | |
|---|
| | 134 | typedef struct |
|---|
| | 135 | { |
|---|
| | 136 | TnyFolder *self; |
|---|
| | 137 | TnyRefreshFolderCallback callback; |
|---|
| | 138 | TnyStatusCallback status_callback; |
|---|
| | 139 | gpointer user_data; |
|---|
| | 140 | gboolean cancelled, expunge; |
|---|
| | 141 | guint depth; |
|---|
| | 142 | GError *err; |
|---|
| | 143 | } SyncFolderInfo; |
|---|
| | 144 | |
|---|
| | 145 | |
|---|
| | 146 | static void |
|---|
| | 147 | sync_async_destroyer (gpointer thr_user_data) |
|---|
| | 148 | { |
|---|
| | 149 | SyncFolderInfo *info = thr_user_data; |
|---|
| | 150 | TnyFolder *self = info->self; |
|---|
| | 151 | |
|---|
| | 152 | /* thread reference */ |
|---|
| | 153 | g_object_unref (G_OBJECT (self)); |
|---|
| | 154 | if (info->err) |
|---|
| | 155 | g_error_free (info->err); |
|---|
| | 156 | |
|---|
| | 157 | g_slice_free (SyncFolderInfo, thr_user_data); |
|---|
| | 158 | |
|---|
| | 159 | return; |
|---|
| | 160 | } |
|---|
| | 161 | |
|---|
| | 162 | static gboolean |
|---|
| | 163 | sync_async_callback (gpointer thr_user_data) |
|---|
| | 164 | { |
|---|
| | 165 | SyncFolderInfo *info = thr_user_data; |
|---|
| | 166 | |
|---|
| | 167 | if (info->callback) |
|---|
| | 168 | info->callback (info->self, info->cancelled, &info->err, info->user_data); |
|---|
| | 169 | |
|---|
| | 170 | return FALSE; |
|---|
| | 171 | } |
|---|
| | 172 | |
|---|
| | 173 | |
|---|
| | 174 | static gpointer |
|---|
| | 175 | sync_async_thread (gpointer thr_user_data) |
|---|
| | 176 | { |
|---|
| | 177 | SyncFolderInfo *info = thr_user_data; |
|---|
| | 178 | TnyFolder *self = info->self; |
|---|
| | 179 | TnyMergeFolderPriv *priv = TNY_MERGE_FOLDER_GET_PRIVATE (self); |
|---|
| | 180 | TnyIterator *iter; |
|---|
| | 181 | GError *err = NULL; |
|---|
| | 182 | |
|---|
| | 183 | g_static_rec_mutex_lock (priv->lock); |
|---|
| | 184 | |
|---|
| | 185 | info->cancelled = FALSE; |
|---|
| | 186 | |
|---|
| | 187 | iter = tny_list_create_iterator (priv->mothers); |
|---|
| | 188 | while (!tny_iterator_is_done (iter)) |
|---|
| | 189 | { |
|---|
| | 190 | TnyFolder *cur = TNY_FOLDER (tny_iterator_get_current (iter)); |
|---|
| | 191 | |
|---|
| | 192 | tny_folder_sync (cur, info->expunge, &err); |
|---|
| | 193 | |
|---|
| | 194 | /* TODO: Handler err */ |
|---|
| | 195 | |
|---|
| | 196 | /* TODO: Handle progress status callbacks ( info->status_callback ) |
|---|
| | 197 | * you might have to start using refresh_async for that (in a |
|---|
| | 198 | * serialized way, else you'd launch a buch of concurrent threads |
|---|
| | 199 | * and ain't going to be nice, perhaps). */ |
|---|
| | 200 | |
|---|
| | 201 | g_object_unref (cur); |
|---|
| | 202 | tny_iterator_next (iter); |
|---|
| | 203 | } |
|---|
| | 204 | g_object_unref (iter); |
|---|
| | 205 | |
|---|
| | 206 | info->err = NULL; |
|---|
| | 207 | |
|---|
| | 208 | g_static_rec_mutex_unlock (priv->lock); |
|---|
| | 209 | |
|---|
| | 210 | if (info->callback) |
|---|
| | 211 | { |
|---|
| | 212 | if (info->depth > 0) |
|---|
| | 213 | { |
|---|
| | 214 | g_idle_add_full (G_PRIORITY_HIGH, |
|---|
| | 215 | sync_async_callback, |
|---|
| | 216 | info, sync_async_destroyer); |
|---|
| | 217 | } else { |
|---|
| | 218 | sync_async_callback (info); |
|---|
| | 219 | sync_async_destroyer (info); |
|---|
| | 220 | } |
|---|
| | 221 | } else /* Thread reference */ |
|---|
| | 222 | g_object_unref (G_OBJECT (self)); |
|---|
| | 223 | |
|---|
| | 224 | g_thread_exit (NULL); |
|---|
| | 225 | |
|---|
| | 226 | return NULL; |
|---|
| | 227 | } |
|---|
| | 228 | |
|---|
| | 229 | |
|---|
| | 230 | static void |
|---|
| | 231 | tny_merge_folder_sync_async (TnyFolder *self, gboolean expunge, TnySyncFolderCallback callback, TnyStatusCallback status_callback, gpointer user_data) |
|---|
| | 232 | { |
|---|
| | 233 | SyncFolderInfo *info; |
|---|
| | 234 | GThread *thread; |
|---|
| | 235 | |
|---|
| | 236 | info = g_slice_new (SyncFolderInfo); |
|---|
| | 237 | info->err = NULL; |
|---|
| | 238 | info->self = self; |
|---|
| | 239 | info->expunge = expunge; |
|---|
| | 240 | info->callback = callback; |
|---|
| | 241 | info->status_callback = status_callback; |
|---|
| | 242 | info->user_data = user_data; |
|---|
| | 243 | info->depth = g_main_depth (); |
|---|
| | 244 | |
|---|
| | 245 | /* thread reference */ |
|---|
| | 246 | g_object_ref (G_OBJECT (self)); |
|---|
| | 247 | |
|---|
| | 248 | thread = g_thread_create (sync_async_thread, info, FALSE, NULL); |
|---|