/* The folder is destroy if it is the last reference. */ void mu_folder_destroy (mu_folder_t *pfolder) { if (pfolder && *pfolder) { mu_folder_t folder = *pfolder; int destroy_lock = 0; mu_monitor_t monitor = folder->monitor; mu_monitor_wrlock (monitor); /* Check if this the last reference for this folder. If yes removed it from the list. */ mu_monitor_wrlock (&folder_lock); folder->ref--; /* Remove the folder from the list of known folder. */ if (folder->ref <= 0) mu_list_remove (known_folder_list, folder); /* If the list is empty we can safely remove it. */ if (mu_list_is_empty (known_folder_list)) mu_list_destroy (&known_folder_list); mu_monitor_unlock (&folder_lock); if (folder->ref <= 0) { mu_monitor_unlock (monitor); destroy_lock = 1; /* Notify the observers. */ if (folder->observable) { mu_observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY, folder); mu_observable_destroy (&folder->observable, folder); } if (folder->_destroy) folder->_destroy (folder); mu_monitor_wrlock (monitor); if (folder->authority) mu_authority_destroy (&folder->authority, folder); if (folder->url) mu_url_destroy (&folder->url); if (folder->property) mu_property_destroy (&folder->property); free (folder); } mu_monitor_unlock (monitor); if (destroy_lock) mu_monitor_destroy (&monitor, folder); *pfolder = NULL; } }
void _mu_sv_instr_pop (mu_sieve_machine_t mach) { if (INSTR_DEBUG (mach)) { mu_sieve_debug (mach, "%4lu: POP\n", (unsigned long)(mach->pc - 1)); if (INSTR_DISASS (mach)) return; } if (!mach->stack || mu_list_is_empty (mach->stack)) { mu_sieve_error (mach, _("stack underflow")); mu_sieve_abort (mach); } mu_list_get (mach->stack, 0, (void **)&mach->reg); mu_list_remove (mach->stack, (void *)mach->reg); }
int mu_msgset_sub_range (mu_msgset_t mset, size_t beg, size_t end, int mode) { int rc; mu_iterator_t itr; struct mu_msgrange *mr; if (!mset) return EINVAL; if (mu_list_is_empty (mset->list)) return MU_ERR_NOENT; if (end && beg > end) { size_t t = end; end = beg; beg = t; } rc = _mu_msgset_translate_pair (mset, mode, &beg, &end); if (rc == MU_ERR_NOENT) return 0; else if (rc) return rc; rc = mu_msgset_aggregate (mset); if (rc) return rc; if (end == MU_MSGNO_LAST) return sub_msgno_last (mset, beg); /* Test border cases */ rc = mu_list_head (mset->list, (void**)&mr); if (rc) return rc; if (end < mr->msg_beg) return 0; if (beg < mr->msg_beg) beg = mr->msg_beg; rc = mu_list_tail (mset->list, (void**) &mr); if (mr->msg_end != MU_MSGNO_LAST) { if (beg > mr->msg_end) return 0; if (end > mr->msg_end) end = mr->msg_end; } rc = mu_list_get_iterator (mset->list, &itr); if (rc) return rc; for (mu_iterator_first (itr); rc == 0 && !mu_iterator_is_done (itr); mu_iterator_next (itr)) { mu_iterator_current (itr, (void **)&mr); if (mr->msg_end == MU_MSGNO_LAST) { /* This is the last element in list. */ if (mr->msg_beg == beg) rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL); else if (mr->msg_beg > beg) mr->msg_beg = end + 1; break; } if (mr->msg_beg == beg && mr->msg_end == end) /* See case 2 above */ { rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL); break; } else if (mr->msg_beg <= beg && beg <= mr->msg_end) { if (mr->msg_beg <= end && end <= mr->msg_end) /* Case 3 */ { /* Split the range */ if (end != mr->msg_end) { struct mu_msgrange *newrange = calloc (1, sizeof (*newrange)); if (!newrange) { rc = ENOMEM; break; } newrange->msg_beg = end + 1; newrange->msg_end = mr->msg_end; rc = mu_iterator_ctl (itr, mu_itrctl_insert, newrange); if (rc) { free (newrange); break; } } if (mr->msg_beg == beg) rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL); else mr->msg_end = beg - 1; break; } else if (mr->msg_beg == beg) /* Case 4 */ { beg = mr->msg_end; rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL); } else { size_t n = mr->msg_end; mr->msg_end = beg - 1; beg = n; } } else if (mr->msg_beg <= end && end <= mr->msg_end) /* Case 5 */ { mr->msg_beg = end + 1; if (mr->msg_beg >= mr->msg_end) rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL); break; } else if (beg <= mr->msg_beg && mr->msg_beg <= end) { rc = mu_iterator_ctl (itr, mu_itrctl_delete, NULL); } } mu_iterator_destroy (&itr); return rc; }