Ejemplo n.º 1
0
Archivo: register.c Proyecto: hawk/otp
BIF_RETTYPE registered_0(BIF_ALIST_0)
{
    int i;
    Eterm res;
    Uint need;
    Eterm* hp;
    HashBucket **bucket;
#ifdef ERTS_SMP
    ErtsProcLocks proc_locks = ERTS_PROC_LOCK_MAIN;

    ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(BIF_P);
    reg_safe_read_lock(BIF_P, &proc_locks);
    if (!proc_locks)
	erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
#endif

    bucket = process_reg.bucket;

    /* work out how much heap we need & maybe garb, by scanning through
       the registered process table */
    need = 0;
    for (i = 0; i < process_reg.size; i++) {
	HashBucket *b = bucket[i];
	while (b != NULL) {
	    need += 2;
	    b = b->next;
	}
    }

    if (need == 0) {
	reg_read_unlock();
	BIF_RET(NIL);
    }

    hp = HAlloc(BIF_P, need);
     
     /* scan through again and make the list */ 
    res = NIL;

    for (i = 0; i < process_reg.size; i++) {
	HashBucket *b = bucket[i];
	while (b != NULL) {
	    RegProc *reg = (RegProc *) b;

	    res = CONS(hp, reg->name, res);
	    hp += 2;
	    b = b->next;
	}
    }

    reg_read_unlock();

    BIF_RET(res);
}
Ejemplo n.º 2
0
Archivo: register.c Proyecto: hawk/otp
void register_info(fmtfn_t to, void *to_arg)
{
    int lock = !ERTS_IS_CRASH_DUMPING;
    if (lock)
	reg_read_lock();
    hash_info(to, to_arg, &process_reg);
    if (lock)
	reg_read_unlock();
}
Ejemplo n.º 3
0
Archivo: register.c Proyecto: hawk/otp
int process_reg_sz(void)
{
    int sz;
    int lock = !ERTS_IS_CRASH_DUMPING;
    if (lock)
	reg_read_lock();
    sz = hash_table_sz(&process_reg);
    if (lock)
	reg_read_unlock();
    return sz;
}
Ejemplo n.º 4
0
Archivo: register.c Proyecto: hawk/otp
int process_reg_size(void)
{
    int size;
    int lock = !ERTS_IS_CRASH_DUMPING;
    if (lock)
	reg_read_lock();
    size = process_reg.size;
    if (lock)
	reg_read_unlock();
    return size;
}
Ejemplo n.º 5
0
Archivo: register.c Proyecto: hawk/otp
Eterm
erts_whereis_name_to_id(Process *c_p, Eterm name)
{
    Eterm res = am_undefined;
    HashValue hval;
    int ix;
    HashBucket* b;
#ifdef ERTS_SMP
    ErtsProcLocks c_p_locks = c_p ? ERTS_PROC_LOCK_MAIN : 0;

#ifdef ERTS_ENABLE_LOCK_CHECK
    if (c_p) ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
#endif

    reg_safe_read_lock(c_p, &c_p_locks);
    if (c_p && !c_p_locks)
        erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
#endif

    hval = REG_HASH(name);
    ix = hval % process_reg.size;
    b = process_reg.bucket[ix];

    /*
     * Note: We have inlined the code from hash.c for speed.
     */
	
    while (b) {
	RegProc* rp = (RegProc *) b;
	if (rp->name == name) {
	    /*
	     * SMP NOTE: No need to lock registered entity since it cannot
	     * be removed without acquiring write reg lock and id on entity
	     * is read only.
	     */
	    if (rp->p)
		res = rp->p->common.id;
	    else if (rp->pt)
		res = rp->pt->common.id;
	    break;
	}
	b = b->next;
    }

    reg_read_unlock();

    ASSERT(is_internal_pid(res) || is_internal_port(res) || res==am_undefined);

    return res;
}
Ejemplo n.º 6
0
Archivo: register.c Proyecto: hawk/otp
void
erts_whereis_name(Process *c_p,
		  ErtsProcLocks c_p_locks,
		  Eterm name,
		  Process** proc,
		  ErtsProcLocks need_locks,
		  int flags,
		  Port** port,
                  int lock_port)
{
    RegProc* rp = NULL;
    HashValue hval;
    int ix;
    HashBucket* b;
#ifdef ERTS_SMP
    ErtsProcLocks current_c_p_locks;
    Port *pending_port = NULL;

    if (!c_p)
	c_p_locks = 0;
    current_c_p_locks = c_p_locks;

 restart:

    reg_safe_read_lock(c_p, &current_c_p_locks);

    /* Locked locks:
     * - port lock on pending_port if pending_port != NULL
     * - read reg lock
     * - current_c_p_locks (either c_p_locks or 0) on c_p
     */
#endif

    hval = REG_HASH(name);
    ix = hval % process_reg.size;
    b = process_reg.bucket[ix];

    /*
     * Note: We have inlined the code from hash.c for speed.
     */

    while (b) {
	if (((RegProc *) b)->name == name) {
	    rp = (RegProc *) b;
	    break;
	}
	b = b->next;
    }

    if (proc) {
	if (!rp)
	    *proc = NULL;
	else {
#ifdef ERTS_SMP
	    if (!rp->p)
		*proc = NULL;
	    else {
		if (need_locks) {
		    erts_proc_safelock(c_p,
				       current_c_p_locks,
				       c_p_locks,
				       rp->p,
				       0,
				       need_locks);
		    current_c_p_locks = c_p_locks;
		}
		if ((flags & ERTS_P2P_FLG_ALLOW_OTHER_X) || is_proc_alive(rp->p))
		    *proc = rp->p;
		else {
		    if (need_locks)
			erts_smp_proc_unlock(rp->p, need_locks);
		    *proc = NULL;
		}
	    }
#else
	    if (rp->p
		&& ((flags & ERTS_P2P_FLG_ALLOW_OTHER_X) || is_proc_alive(rp->p)))
		*proc = rp->p;
	    else
		*proc = NULL;
#endif
	    if (*proc && (flags & ERTS_P2P_FLG_INC_REFC))
		erts_proc_inc_refc(*proc);
	}
    }

    if (port) {
	if (!rp || !rp->pt)
	    *port = NULL;
	else {
#ifdef ERTS_SMP
            if (lock_port) {
                if (pending_port == rp->pt)
                    pending_port = NULL;
                else {
                    if (pending_port) {
                        /* Ahh! Registered port changed while reg lock
                           was unlocked... */
                        erts_port_release(pending_port);
                        pending_port = NULL;
                    }
		    
                    if (erts_smp_port_trylock(rp->pt) == EBUSY) {
                        Eterm id = rp->pt->common.id; /* id read only... */
                        /* Unlock all locks, acquire port lock, and restart... */
                        if (current_c_p_locks) {
                            erts_smp_proc_unlock(c_p, current_c_p_locks);
                            current_c_p_locks = 0;
                        }
                        reg_read_unlock();
                        pending_port = erts_id2port(id);
                        goto restart;
                    }
                }
                ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(rp->pt));
            }
#endif
	    *port = rp->pt;
	}
    }

#ifdef ERTS_SMP
    if (c_p && !current_c_p_locks)
	erts_smp_proc_lock(c_p, c_p_locks);
    if (pending_port)
	erts_port_release(pending_port);
#endif

    reg_read_unlock();
}
Ejemplo n.º 7
0
/*
 * Unregister a name
 * Return 0 if not registered
 * Otherwise returns 1
 *
 */
int erts_unregister_name(Process *c_p,
			 ErtsProcLocks c_p_locks,
			 Port *c_prt,
			 Eterm name)
{
    int res = 0;
    RegProc r, *rp;
    Port *port = c_prt;
#ifdef ERTS_SMP
    ErtsProcLocks current_c_p_locks;

    /*
     * SMP note: If 'c_prt != NULL' and 'c_prt->reg->name == name',
     *           we are *not* allowed to temporarily release the lock
     *           on c_prt.
     */

    if (!c_p)
	c_p_locks = 0;
    current_c_p_locks = c_p_locks;

 restart:

    reg_safe_write_lock(c_p, &current_c_p_locks);
#endif
    
    r.name = name;
    if ((rp = (RegProc*) hash_get(&process_reg, (void*) &r)) != NULL) {
	if (rp->pt) {
#ifdef ERTS_SMP
	    if (port != rp->pt) {
		if (port) {
		    ERTS_SMP_LC_ASSERT(port != c_prt);
		    erts_smp_port_unlock(port);
		    port = NULL;
		}

		if (erts_smp_port_trylock(rp->pt) == EBUSY) {
		    Eterm id = rp->pt->id; /* id read only... */
		    /* Unlock all locks, acquire port lock, and restart... */
		    if (current_c_p_locks) {
			erts_smp_proc_unlock(c_p, current_c_p_locks);
			current_c_p_locks = 0;
		    }
		    reg_read_unlock();
		    port = erts_id2port(id, NULL, 0);
		    goto restart;
		}
		port = rp->pt;
	    }
#endif
	    ERTS_SMP_LC_ASSERT(rp->pt == port && erts_lc_is_port_locked(port));
	    rp->pt->reg = NULL;
	    
	    if (IS_TRACED_FL(port, F_TRACE_PORTS)) {
		trace_port(port, am_unregister, name);
	    }

	} else if (rp->p) {
	    Process* p = rp->p;
#ifdef ERTS_SMP
	    erts_proc_safelock(c_p,
			       current_c_p_locks,
			       c_p_locks,
			       rp->p,
			       0,
			       ERTS_PROC_LOCK_MAIN);
	    current_c_p_locks = c_p_locks;
#endif
	    p->reg = NULL;
#ifdef ERTS_SMP
	    if (rp->p != c_p)
		erts_smp_proc_unlock(rp->p, ERTS_PROC_LOCK_MAIN);
#endif
	    if (IS_TRACED_FL(p, F_TRACE_PROCS)) {
		trace_proc(c_p, p, am_unregister, name);
	    }
	}
	hash_erase(&process_reg, (void*) &r);
	res = 1;
    }

    reg_write_unlock();
    if (c_prt != port) {
	if (port)
	    erts_smp_port_unlock(port);
	if (c_prt)
	    erts_smp_port_lock(c_prt);
    }
#ifdef ERTS_SMP
    if (c_p && !current_c_p_locks)
	erts_smp_proc_lock(c_p, c_p_locks);
#endif
    return res;
}