Beispiel #1
0
/*
 * Connection daemon has recieved a message from the event master
 * that a new class is available for this member.  This function
 * registers that new class.
 */
int
EvRemoteRegisterEventClass(EvGroupID_t groupID, char *className,
                           EvAccess_t groupAccessCode,
                           EvAccess_t classAccessCode,
                           int error, EvClassID_t classID)
{
    EvGroupInfo_t *EGroup;
    EvPendRem_t *Pend;
    EvClassInfo_t *HashBase;
    unsigned long Flags;
    int RetVal;

    read_lock_irqsave(&EvGroupLock, Flags);
    if ((EGroup = EvGetGroupBase(groupID)) == NULL) {
        read_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_EXIST;
    }

    write_lock(&EGroup->EgiLock);
    read_unlock(&EvGroupLock);

    /* Pend the pending control struct for this ID.
     *
     * If Pend is NULL then this is the master reporting a new event
     * class.
     */
    if ((Pend = EvFindPendEntry(EGroup, EV_REM_REGISTER_EVENT_CLASS,
                                groupAccessCode, classAccessCode, 0, 0,
                                strlen(className)+1, className)) != NULL) {
        /* Fill in the return values. */
        Pend->PrRetInfo.EpInfo[0] = error;
        Pend->PrRetInfo.EpInfo[1] = classID;

        /* Wake up the requester. */
        wake_up_interruptible(&Pend->PrWaitQ);

        write_unlock_irqrestore(&EGroup->EgiLock, Flags);
        return EV_NOERR;
    }

    /* Register a new event class on a group member for the master. */
    HashBase = EvGetHashBase(EGroup, classID);

    while (HashBase->EciNext != NULL) {
        HashBase = HashBase->EciNext;
    }

    RetVal=EvFillInHashInfo(HashBase, classAccessCode, className, &classID);

    write_unlock_irqrestore(&EGroup->EgiLock, Flags);
    return RetVal;
}
Beispiel #2
0
/*
 * The EvRegisterEventClass() function registers the className string as the
 * identifier of an event class and returns a unique token to identify that
 * class.  The class is created as a part of an event group.
 *
 * If the event group is local then the event class is created as a part
 * of the local events and can be used only on the registering system.  If
 * this system is the master for an event group then a local identity is
 * created on this system and notification is sent to remote systems to
 * inidcate this event has been created.  If this event group is a member
 * on this system then the master is told to register this event class and
 * return the class ID and then a local copy of the registeration is made.
 *
 * If the event group defined by groupID does not exist then -EEXIST is
 * returned and no class is registered.  If the event class defined by
 * className already exists -EBUSY is returned and not class is registered.
 * returned.  If the kernel could not allocate enough memory for the
 * controling data structures -ENOSPC is returned and not class is
 * registered.  Otherwise the class identified by className is registered,
 * a unique ID is allocated and placed in the class parameter and a
 * zero is returned to indicate success.
 */
int
EvRegisterEventClass(EvGroupID_t groupID, char *className,
		     EvAccess_t groupAccessCode, EvAccess_t classAccessCode,
		     EvClassID_t *classID)
{
	EvGroupInfo_t *EGroup;
	EvClassInfo_t *HashBase;
	unsigned long Flags;
	int RetVal;

	/* Get the group info pointer and return with it locked. */
	if ((RetVal = EvLockAndGetGroup(groupID, EV_ACCESS_CHECK,
					groupAccessCode, &Flags,
					EV_LOCK_GROUP_WRITE, &EGroup))) {
		return RetVal;
	}

	/* Check to see if the class already exists */
	if (EvCheckEventClass(EGroup, className, classID) > -1) {
		write_unlock_irqrestore(&EGroup->EgiLock, Flags);
		return -EV_ERROR_CLASS_EXISTS;
	}

	/* If the event class is not a local one then send a register to
	 * the remote master.  The remote master returns the class ID.
	 */
	if ((EGroup->EgiType == EG_MEMBER) && EGroup->EgiNextClass) {
		if ((RetVal = EvSendRegEventClass(EGroup, className,
						  groupAccessCode,
						  classAccessCode,
						  classID, &Flags)) < 0) {
			write_unlock_irqrestore(&EGroup->EgiLock, Flags);
			return RetVal;
		}
	} else {
		/* Class is locally assigned */
		*classID = EGroup->EgiNextClass++;

		/* If this is an event master then send class create event. */
		if (EGroup->EgiType == EG_MASTER) {
			if ((RetVal = EvSendRegClassToMembers(EGroup, className,
					        groupAccessCode,
						classAccessCode, *classID))) {
			write_unlock_irqrestore(&EGroup->EgiLock, Flags);
			return RetVal;
			}
		}
	}

	HashBase = EvGetHashBase(EGroup, *classID);

	while (HashBase->EciNext != NULL) {
		HashBase = HashBase->EciNext;
	}

	RetVal=EvFillInHashInfo(HashBase, classAccessCode, className, classID);

	EGroup->EgiUseCount++;

	write_unlock_irqrestore(&EGroup->EgiLock, Flags);
	return RetVal;
}