📄 rvmegacoentity.c
字号:
return entity;
}
/*$
{function:
{name: rvMegacoEntityDestruct}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Destroys an entity object.}
}
{proto: void rvMegacoEntityDestruct(RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity object.}}
}
}
$*/
void rvMegacoEntityDestruct(RvMegacoEntity *entity)
{
RvTransport *transport = &entity->stack->transport;
RvSocketListener * sl;
entity->dead = rvTrue;
if(entity->socket != NULL)
sl = rvTransportUnregisterSocket(transport, entity->socket);
if(!entity->isLocal)
rvMegacoEntitySendNow(entity);
rvMegacoEntityDeleteAllTcbs(entity);
if(entity->socket != NULL)
rvTransportRemoveUnregisteredSocket(transport, entity->socket, sl);
if(entity->isLocal)
rvMegacoEntityDeleteAllRemotes(entity);
else
rvMegacoEntityRemoveRemote(entity->u.remote.localEntity, &entity->mId);
rvMutexDestruct(&entity->mutex);
rvMegacoEntityAddressDestruct(&entity->mId);
rvHashDestruct(RvMegacoTransactionId, RvMegacoTcbPtr)(&entity->tcbs);
if(entity->isLocal)
{
rvHashDestruct(RvMegacoEntityAddress, RvMegacoEntityPtr)(&entity->u.local.remotes);
rvRandomGeneratorDestruct(&entity->u.local.randomGenerator);
}
else
{
rvSocketAddrDestruct(&entity->u.remote.socketAddr);
rvPtrListDestruct(&entity->u.remote.transactionsToSend);
rvStrStreamDestruct(&entity->u.remote.msgStream);
rvMegacoResponseAckDestruct(&entity->u.remote.acks);
rvTimerDestruct(&entity->u.remote.sendTimer);
rvRoundTripStatsDestruct(&entity->u.remote.roundTripStats);
}
}
/*$
{function:
{name: rvMegacoEntityGetAddress}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Gets the address of an entity.}
}
{proto: const RvMegacoEntityAddress *rvMegacoEntityGetAddress(const RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity object.}}
}
{returns: The address of the entity.}
}
$*/
const RvMegacoEntityAddress *rvMegacoEntityGetAddress(const RvMegacoEntity *entity)
{
return &entity->mId;
}
/*$
{function:
{name: rvMegacoEntityIsPrimary}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Check if an entity is the primary entity in a set of redundant entities.}
}
{proto: RvBool rvMegacoEntityIsPrimary(const RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity.}}
}
{returns: rvTrue if the entity is a primary entity, rvFalse if the entity is a secondary entity.}
}
$*/
RvBool rvMegacoEntityIsPrimary(const RvMegacoEntity *entity)
{
return entity->primary;
}
/*$
{function:
{name: rvMegacoEntityGetType}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Gets the type of the entity object, MG or MGC.}
}
{proto: RvMegacoEntityType rvMegacoEntityGetType(const RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity object.}}
}
{returns: The type.}
}
$*/
RvMegacoEntityType rvMegacoEntityGetType(const RvMegacoEntity *entity)
{
return entity->entityType;
}
/*$
{function:
{name: rvMegacoEntityGetTransportType}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Gets the transport type of an entity.}
}
{proto: RvTransportType rvMegacoEntityGetTransportType(const RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity object.}}
}
{returns: The transport type of the entity.}
}
$*/
RvTransportType rvMegacoEntityGetTransportType(const RvMegacoEntity *entity)
{
return entity->transportType;
}
/*$
{function:
{name: rvMegacoEntityGetEncoding}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Gets the encoding type of an entity.}
}
{proto: RvMegacoEncoding rvMegacoEntityGetEncoding(const RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity object.}}
}
{returns: The encoding type of the entity.}
}
$*/
RvMegacoEncoding rvMegacoEntityGetEncoding(const RvMegacoEntity *entity)
{
return entity->encoding;
}
/*$
{function:
{name: rvMegacoEntityGetLocalEntity}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Gets the local entity that a remote entity communicates with.}
}
{proto: RvMegacoEntity *rvMegacoEntityGetLocalEntity(const RvMegacoEntity *remote);}
{params:
{param: {n:remote} {d:The remote entity.}}
}
{returns: The local entity.}
}
$*/
RvMegacoEntity *rvMegacoEntityGetLocalEntity(const RvMegacoEntity *remote)
{
assert(!remote->isLocal);
return remote->u.remote.localEntity;
}
/*$
{function:
{name: rvMegacoEntityFindRemote}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Find a remote entity by its address.}
}
{proto: RvMegacoEntity *rvMegacoEntityFindRemote(RvMegacoEntity *local, const RvMegacoEntityAddress *remoteAddress);}
{params:
{param: {n:local} {d:The local entity.}}
{param: {n:remoteAddress} {d:The remote address.}}
}
{returns: The remote entity, or NULL if the remote entity was not found.}
}
$*/
RvMegacoEntity *rvMegacoEntityFindRemote(RvMegacoEntity *local, const RvMegacoEntityAddress *remoteAddress)
{
RvMegacoEntity **entity;
assert(local->isLocal);
entity = rvHashFind(RvMegacoEntityAddress, RvMegacoEntityPtr)(&local->u.local.remotes, (RvMegacoEntityAddress *)remoteAddress);
return entity == NULL ? NULL : *entity;
}
/*$
{function:
{name: rvMegacoEntityMakePrimary}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Make an entity the primary entity in a set of redundant entities.}
}
{proto: void rvMegacoEntityMakePrimary(RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity.}}
}
}
$*/
void rvMegacoEntityMakePrimary(RvMegacoEntity *entity)
{
entity->primary = rvTrue;
}
/*$
{function:
{name: rvMegacoEntityMakeSecondary}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Make an entity a secondary entity in a set of redundant entities.}
}
{proto: void rvMegacoEntityMakeSecondary(RvMegacoEntity *entity);}
{params:
{param: {n:entity} {d:The entity.}}
}
}
$*/
void rvMegacoEntityMakeSecondary(RvMegacoEntity *entity)
{
entity->primary = rvFalse;
}
/*$
{function:
{name: rvMegacoEntityRegisterRecvRequestCB}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Registers a callback that will be invoked for each parsed transaction request that
this local entity receives.}
}
{proto: void rvMegacoEntityRegisterRecvRequestCB(RvMegacoEntity *local, RvMegacoRecvRequestCB f, void *data);}
{params:
{param: {n:local} {d:The local entity.}}
{param: {n:f} {d:The callback.}}
{param: {n:data} {d:User data that will be passed to the callback.}}
}
}
$*/
void rvMegacoEntityRegisterRecvRequestCB(RvMegacoEntity *local, RvMegacoRecvRequestCB f, void *data)
{
assert(local->isLocal);
local->u.local.processRequest = f;
local->u.local.processRequestData = data;
}
/*$
{function:
{name: rvMegacoEntityRegisterRecvErrorMsgCB}
{class: RvMegacoEntity}
{include: rvmegacoentity.h}
{description:
{p: Registers a callback that will be invoked for any message received by this local entity
that contains only an error descriptor.}
}
{proto: void rvMegacoEntityRegisterRecvErrorMsgCB(RvMegacoEntity *local, RvMegacoRecvErrorMsgCB f, void *data);}
{params:
{param: {n:local} {d:The local entity.}}
{param: {n:f} {d:The callback.}}
{param: {n:data} {d:User data that will be passed to the callback.}}
}
}
$*/
void rvMegacoEntityRegisterRecvErrorMsgCB(RvMegacoEntity *local, RvMegacoRecvErrorMsgCB f, void *data)
{
assert(local->isLocal);
local->u.local.processError = f;
local->u.local.processErrorData = data;
}
/* private: */
const RvSocketAddr *rvMegacoEntityGetSocketAddr(const RvMegacoEntity *remote)
{
assert(!remote->isLocal);
return &remote->u.remote.socketAddr;
}
void rvMegacoEntitySetSocketAddr(RvMegacoEntity *remote, const RvSocketAddr *socketAddr)
{
assert(!remote->isLocal);
rvSocketAddrCopy(&remote->u.remote.socketAddr, socketAddr);
}
RvSocket *rvMegacoEntityGetSocket(RvMegacoEntity *entity)
{
return entity->socket;
}
void rvMegacoEntitySetSocket(RvMegacoEntity *entity, RvSocket *socket)
{
if(entity->socket != NULL && !rvSocketEqual(socket, entity->socket))
rvTransportRemoveSocket(&entity->stack->transport, entity->socket);
entity->socket = socket;
}
void rvMegacoEntityOnSocketDelete(RvSocket *socket, void *data)
{
RvMegacoEntity *entity = (RvMegacoEntity *)data;
RvHashIter(RvMegacoEntityAddress, RvMegacoEntityPtr) iter;
RvHashIter(RvMegacoEntityAddress, RvMegacoEntityPtr) end =
rvHashEnd(RvMegacoEntityAddress, RvMegacoEntityPtr)(&entity->u.local.remotes);
for(iter = rvHashBegin(RvMegacoEntityAddress, RvMegacoEntityPtr)(&entity->u.local.remotes);
!rvHashIterEqual(RvMegacoEntityAddress, RvMegacoEntityPtr)(&iter, &end);
iter = rvHashIterNext(RvMegacoEntityAddress, RvMegacoEntityPtr)(iter))
{
RvMegacoEntity *remote = *rvHashIterData(RvMegacoEntityAddress, RvMegacoEntityPtr)(iter);
if(remote->socket == socket)
{
rvMutexLock(&remote->mutex);
remote->socket = NULL;
rvMutexUnlock(&remote->mutex);
}
}
}
void rvMegacoEntitySetDeleteFlag(RvMegacoEntity *remote)
{
assert(!remote->isLocal);
remote->u.remote.deleteMe = rvTrue;
}
void rvMegacoEntityRemoveRemote(RvMegacoEntity *local, const RvMegacoEntityAddress *remoteAddress)
{
assert(local->isLocal);
rvHashEraseKey(RvMegacoEntityAddress, RvMegacoEntityPtr)(&local->u.local.remotes, remoteAddress);
}
RvMegacoTransactionId rvMegacoEntityGetNextTransactionId(RvMegacoEntity *local)
{
assert(local->isLocal);
if(local->u.local.nextTransactionId == 1000000)
local->u.local.nextTransactionId = 1;
return local->u.local.nextTransactionId++;
}
void rvMegacoEntityAddTcb(RvMegacoEntity *entity, RvMegacoTcb *tcb)
{
RvMegacoTransactionId tId = rvMegacoTcbGetId(tcb);
rvMutexLock(&entity->mutex);
rvHashInsertUnique(RvMegacoTransactionId, RvMegacoTcbPtr)(&entity->tcbs, &tId, &tcb);
rvMutexUnlock(&entity->mutex);
}
void rvMegacoEntityRemoveTcb(RvMegacoEntity *entity, RvMegacoTransactionId tId)
{
rvMutexLock(&entity->mutex);
rvHashEraseKey(RvMegacoTransactionId, RvMegacoTcbPtr)(&entity->tcbs, &tId);
rvMutexUnlock(&entity->mutex);
}
RvMegacoTcb *rvMegacoEntityFindTcb(RvMegacoEntity *entity, RvMegacoTransactionId tId)
{
RvMegacoTcb **tcb;
rvMutexLock(&entity->mutex);
tcb = rvHashFind(RvMegacoTransactionId, RvMegacoTcbPtr)(&entity->tcbs, &tId);
rvMutexUnlock(&entity->mutex);
return tcb == NULL ? NULL : *tcb;
}
void rvMegacoEntityAddResponseAck(RvMegacoEntity *remote, RvMegacoTransactionId tId)
{
assert(!remote->isLocal);
rvMutexLock(&remote->mutex);
rvMegacoResponseAckAdd(&remote->u.remote.acks, tId);
rvMutexUnlock(&remote->mutex);
}
void rvMegacoEntityUpdateRoundTripTime(RvMegacoEntity *remote, RvHrtime roundTripTime)
{
assert(!remote->isLocal);
rvRoundTripStatsUpdate(&remote->u.remote.roundTripStats, roundTripTime);
}
RvHrtime rvMegacoEntityGetFirstRetransTimeout(RvMegacoEntity *remote)
{
assert(!remote->isLocal);
return rvRoundTripStatsGetFirstRetransTimeout(&remote->u.remote.roundTripStats, &remote->stack->timeoutLimits);
}
RvHrtime rvMegacoEntityGetNextRetransTimeout(RvMegacoEntity *remote)
{
assert(!remote->isLocal);
return rvRoundTripStatsGetNextRetransTimeout(&remote->u.remote.roundTripStats, &remote->stack->timeoutLimits);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -