+
+static void delete_imap_run(struct etpan_thread_op * op)
+{
+ mailimap * imap = op->imap;
+
+ /* we don't want libetpan to logout */
+ if (imap->imap_stream) {
+ mailstream_close(imap->imap_stream);
+ imap->imap_stream = NULL;
+ }
+
+ mailimap_free(imap);
+}
+
+static void threaded_delete_imap(Folder *folder, mailimap *imap)
+{
+ struct etpan_thread_op * op;
+
+ /* No need to wait for completion, threaded_run() won't work here. */
+ op = etpan_thread_op_new();
+ op->imap = imap;
+ op->run = delete_imap_run;
+ op->cleanup = etpan_thread_op_free;
+
+ etpan_thread_op_schedule(get_thread(folder), op);
+
+ debug_print("threaded delete imap posted\n");
+}
+
+static void delete_imap(Folder *folder, mailimap *imap)
+{
+ chashdatum key;
+
+ key.data = &folder;
+ key.len = sizeof(folder);
+ chash_delete(session_hash, &key, NULL);
+
+ if (!imap)
+ return;
+ key.data = &imap;
+ key.len = sizeof(imap);
+ chash_delete(courier_workaround_hash, &key, NULL);
+ /* We can't just free imap here as there may be ops on it pending
+ * in the thread. Posting freeing as an op will synchronize against
+ * existing jobs and as imap is already removed from session_hash
+ * we are sure no new ops can be posted. */
+ threaded_delete_imap(folder, imap);
+}
+