示例#1
0
void SyncUser::log_out()
{
    if (m_is_admin) {
        // Admin users cannot be logged out.
        return;
    }
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_state == State::LoggedOut) {
        return;
    }
    m_state = State::LoggedOut;
    // Move all active sessions into the waiting sessions pool. If the user is
    // logged back in, they will automatically be reactivated.
    for (auto& pair : m_sessions) {
        if (auto ptr = pair.second.lock()) {
            ptr->log_out();
            m_waiting_sessions[pair.first] = ptr;
        }
    }
    m_sessions.clear();
    // Mark the user as 'dead' in the persisted metadata Realm.
    if (!m_is_admin) {
        SyncManager::shared().perform_metadata_update([=](const auto& manager) {
            auto metadata = SyncUserMetadata(manager, m_identity, false);
            metadata.mark_for_removal();
        });
    }
}
示例#2
0
static int
rwlock_unlock(int semid, struct semid_pool *semaptr) {
	sysv_print("unlock id = %d %x\n", semid, semaptr);
	if (!sema_exist(semid, semaptr)) {
		/* Internal resources must be freed. */
		mark_for_removal(semid);
		errno = EINVAL;
		return (-1);
	}
#ifdef SYSV_RWLOCK
	sysv_rwlock_unlock(&semaptr->rwlock);
#else
	sysv_mutex_unlock(&semaptr->mutex);
#endif
	return (0);
}
示例#3
0
static int
try_rwlock_wrlock(int semid, struct semid_pool *semaptr) {
#ifdef SYSV_RWLOCK
	sysv_print("before wrlock id = %d %x\n", semid, semaptr);
	sysv_rwlock_wrlock(&semaptr->rwlock);
#else
	sysv_print("before lock id = %d %x\n", semid, semaptr);
	sysv_mutex_lock(&semaptr->mutex);
#endif
	sysv_print("lock id = %d\n", semid);
	if (!sema_exist(semid, semaptr)) {
		errno = EINVAL;
		sysv_print("error sema %d doesn't exist\n", semid);
#ifdef SYSV_RWLOCK
		sysv_rwlock_unlock(&semaptr->rwlock);
#else
		sysv_mutex_unlock(&semaptr->mutex);
#endif
		/* Internal resources must be freed. */
		mark_for_removal(semid);
		return (-1);
	}
	return (0);
}
示例#4
0
文件: simp.c 项目: semitrivial/poral
/*
 * We simplify the pattern recursively, using node "start" as a
 * "zipper" to zip the pattern up ("start" moves from left to
 * right as the recursion proceeds, and the recusion ends when
 * "start" reaches the end of the pattern).
 *
 * Overall strategy: We "check" whether we can remove "start" without
 * changing what ordinal the pointed pattern notates.  But if we remove
 * "start", we have to remove anything connected to it (via less1,
 * or via decompositions), so we have to ask the same question about
 * all those nodes as well, which in turn requires asking the same
 * question about any node THEY'RE connected to, and so on.
 */
static pattern *simplify_recurse( pattern *p, node *start )
{
  node *n;
  pattern *q;

  /*
   * Mark all nodes in the pattern as being unchecked during this iteration
   */
  for ( n = p->first_node; n; n = n->next )
    n->simplify_data = SIMPL_UNCHECKED;

  /*
   * Under no circumstances would we remove the pattern's designated point
   */
  if ( start == p->point )
  {
    start = start->next;
    if ( !start )
      return p;
  }

  /*
   * Attempt to mark "start" for removal.
   * If the attempt fails (because it would
   * require removing p->point) then move on
   * to the next start.
   */
  if ( ! mark_for_removal(p,start,start) )
  {
    if ( !start->next )
      return p;
    return simplify_recurse( p, start->next );
  }

  /*
   * If "start" was successfully marked for
   * removal, then remove it, along with anything
   * else that was marked as collateral damage.
   * Actually, do all this in a copy q of p.
   */
  q = execute_removal(p);

  /*
   * Check whether the copy q, with "start" removed,
   * still notates the same ordinal that p does.
   * If so, continue trying to further simplify q.
   * If not, revert back to p and increment "start".
   */
  if ( same_point(q,p) )
  {
    start = isom(start,q);

    if ( start )
      return simplify_recurse( q, start );
    else
      return q;
  }
  else
  {
    if ( start->next )
      return simplify_recurse( p, start->next );
    else
      return p;
  }
}
示例#5
0
文件: simp.c 项目: semitrivial/poral
/*
 * Attempt to mark a node x for removal, along with (recursively)
 * all nodes that would also have to be removed if that node were.
 * Returns 0 if the pattern's designated point would have to be
 * removed.  The node *start input keeps track of which node we
 * were originally wanting to remove (before getting lost in the
 * mazes of recursion).
 */
static int mark_for_removal( pattern *p, node *x, node *start )
{
  node *n, **d, *L;

  if ( x == p->point )
    return 0;

  /*
   * Black-magic shortcut:
   *  if the point we're recursively trying to mark is further left
   *  than the original point we care about marking, then marking
   *  x would force us to mark p->point.  Why?  Because if we could
   *  have marked x, then we would have done so already, in simplify_recurse,
   *  before even considering "start".
   */
  if ( x->position < start->position )
    return 0;

  /*
   * If x is the left endpoint of a circle and p->point lies within that
   * circle, then we cannot mark x for removal without marking p->point
   */
  if ( x->position <= p->point->position
  &&   p->point->position <= x->less1->position )
    return 0;

  /*
   * If we've already marked x for removal, there's nothing left to do.
   */
  if ( x->simplify_data == SIMPL_MARKED )
    return 1;

  /*
   * Mark x for removal.
   */
  x->simplify_data = SIMPL_MARKED;

  /*
   * Now recursively mark for removal all things which would have to
   * be removed if we remove x.
   */
  for ( n = x->next; n; n = n->next )
  {
    /*
     * Anything which is a decomposition involving doomed nodes, is doomed.
     */
    if ( n->decomposition )
    {
      for ( d = n->decomposition; *d; d++ )
      {
        if ( (*d)->simplify_data == SIMPL_MARKED )
          break;
      }
      if ( *d )
      {
        if ( !mark_for_removal( p, n, start ) )
          return 0;
      }
      else
      {
        /*
         * Suppose n=x_1+...+x_n (a descending sum of indecomposables), and none
         * of the x_i have been marked for removal.  It will still be necessary
         * to mark n for removal if any of x_1+...+x_(n-i) are marked.
         */
        node *d_bak; // backup of *d
        node *acl; // "arithmetical closure"

        for ( d = n->decomposition; *d; d++ )
        {
          d_bak = *d;
          *d = NULL;
          acl = get_node_by_decomposition( p, n->decomposition );
          *d = d_bak;
          if ( acl == n )
            continue;
          if ( acl->simplify_data == SIMPL_MARKED )
            break;
        }
        if ( *d )
        {
          if ( !mark_for_removal( p, n, start ) )
            return 0;
        }
      }
    }
  }

  /*
   * If x is the left endpoint of a less1-circle, then to remove x,
   * we must remove everything within that circle.
   */
  if ( x->less1 != x )
  {
    for ( n = x->next; n->position <= x->less1->position; n = n->next )
    {
      if ( !mark_for_removal( p, n, start ) )
        return 0;
    }
  }
  else
  {
    /*
     * Otherwise, consider the case whether x is the right endpoint of
     * a less1-circle.  We search for the leftmost (if any) node L such
     * that L is the left-endpoint of a circle whose right endpoint is x.
     */
    for ( L = p->first_node; L; L = L->next )
    {
      if ( L == x )
        break;
      if ( L->less1 == x )
        break;
      if ( L->less1->position < x->position )
        L = L->less1;
    }

    /*
     * If we found a circle with left endpoint L and right endpoint x,
     * we are obliged to remove that circle and everything inside it.
     */
    if ( L && L != x )
    {
      for ( n = L; L->position < x->position; L++ )
      {
        if ( !mark_for_removal( p, n, start ) )
          return 0;
      }
    }
  }

  return 1;
}