/* * 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; }
/* * 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; }