Пример #1
0
/* 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;
    }
}
Пример #2
0
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);
}
Пример #3
0
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;
}