New upstream version 8.1.0
This commit is contained in:
20
client_module/source/common/toolkit/ackstore/AckStoreMap.c
Normal file
20
client_module/source/common/toolkit/ackstore/AckStoreMap.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "AckStoreMap.h"
|
||||
#include "AckStoreMapIter.h"
|
||||
|
||||
AckStoreMapIter AckStoreMap_find(AckStoreMap* this, const char* searchKey)
|
||||
{
|
||||
RBTreeElem* treeElem = _PointerRBTree_findElem( (RBTree*)this, searchKey);
|
||||
|
||||
AckStoreMapIter iter;
|
||||
AckStoreMapIter_init(&iter, this, treeElem);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
int compareAckStoreMapElems(const void* key1, const void* key2)
|
||||
{
|
||||
return strcmp(key1, key2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
117
client_module/source/common/toolkit/ackstore/AckStoreMap.h
Normal file
117
client_module/source/common/toolkit/ackstore/AckStoreMap.h
Normal file
@@ -0,0 +1,117 @@
|
||||
#ifndef ACKSTOREMAP_H_
|
||||
#define ACKSTOREMAP_H_
|
||||
|
||||
#include <common/toolkit/tree/PointerRBTree.h>
|
||||
#include <common/toolkit/tree/PointerRBTreeIter.h>
|
||||
#include "WaitAckMap.h"
|
||||
|
||||
|
||||
struct AckStoreEntry;
|
||||
typedef struct AckStoreEntry AckStoreEntry;
|
||||
|
||||
|
||||
struct AckStoreMapElem;
|
||||
typedef struct AckStoreMapElem AckStoreMapElem;
|
||||
struct AckStoreMap;
|
||||
typedef struct AckStoreMap AckStoreMap;
|
||||
|
||||
struct AckStoreMapIter; // forward declaration of the iterator
|
||||
|
||||
|
||||
static inline void AckStoreEntry_init(AckStoreEntry* this, char* ackID,
|
||||
WaitAckMap* waitMap, WaitAckMap* receivedMap, WaitAckNotification* notifier);
|
||||
static inline AckStoreEntry* AckStoreEntry_construct(char* ackID,
|
||||
WaitAckMap* waitMap, WaitAckMap* receivedMap, WaitAckNotification* notifier);
|
||||
static inline void AckStoreEntry_destruct(AckStoreEntry* this);
|
||||
|
||||
|
||||
static inline void AckStoreMap_init(AckStoreMap* this);
|
||||
static inline void AckStoreMap_uninit(AckStoreMap* this);
|
||||
|
||||
static inline bool AckStoreMap_insert(AckStoreMap* this, char* newKey,
|
||||
AckStoreEntry* newValue);
|
||||
static inline bool AckStoreMap_erase(AckStoreMap* this, const char* eraseKey);
|
||||
|
||||
extern struct AckStoreMapIter AckStoreMap_find(AckStoreMap* this, const char* searchKey);
|
||||
|
||||
extern int compareAckStoreMapElems(const void* key1, const void* key2);
|
||||
|
||||
|
||||
struct AckStoreEntry
|
||||
{
|
||||
char* ackID;
|
||||
|
||||
WaitAckMap* waitMap; // ack will be removed from this map if it is received
|
||||
WaitAckMap* receivedMap; // ack will be added to this map if it is received
|
||||
|
||||
WaitAckNotification* notifier;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct AckStoreMapElem
|
||||
{
|
||||
RBTreeElem rbTreeElem;
|
||||
};
|
||||
|
||||
struct AckStoreMap
|
||||
{
|
||||
RBTree rbTree;
|
||||
};
|
||||
|
||||
|
||||
void AckStoreEntry_init(AckStoreEntry* this, char* ackID,
|
||||
WaitAckMap* waitMap, WaitAckMap* receivedMap, WaitAckNotification* notifier)
|
||||
{
|
||||
this->ackID = ackID;
|
||||
this->waitMap = waitMap;
|
||||
this->receivedMap = receivedMap;
|
||||
this->notifier = notifier;
|
||||
}
|
||||
|
||||
AckStoreEntry* AckStoreEntry_construct(char* ackID,
|
||||
WaitAckMap* waitMap, WaitAckMap* receivedMap, WaitAckNotification* notifier)
|
||||
{
|
||||
AckStoreEntry* this = (AckStoreEntry*)os_kmalloc(sizeof(*this) );
|
||||
|
||||
AckStoreEntry_init(this, ackID, waitMap, receivedMap, notifier);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void AckStoreEntry_destruct(AckStoreEntry* this)
|
||||
{
|
||||
kfree(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AckStoreMap_init(AckStoreMap* this)
|
||||
{
|
||||
PointerRBTree_init( (RBTree*)this, compareAckStoreMapElems);
|
||||
}
|
||||
|
||||
void AckStoreMap_uninit(AckStoreMap* this)
|
||||
{
|
||||
PointerRBTree_uninit( (RBTree*)this);
|
||||
}
|
||||
|
||||
bool AckStoreMap_insert(AckStoreMap* this, char* newKey, AckStoreEntry* newValue)
|
||||
{
|
||||
bool insRes;
|
||||
|
||||
insRes = PointerRBTree_insert( (RBTree*)this, newKey, newValue);
|
||||
if(!insRes)
|
||||
{
|
||||
// not inserted because the key already existed
|
||||
}
|
||||
|
||||
return insRes;
|
||||
}
|
||||
|
||||
bool AckStoreMap_erase(AckStoreMap* this, const char* eraseKey)
|
||||
{
|
||||
return PointerRBTree_erase( (RBTree*)this, eraseKey);
|
||||
}
|
||||
|
||||
#endif /* ACKSTOREMAP_H_ */
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef ACKSTOREMAPITER_H_
|
||||
#define ACKSTOREMAPITER_H_
|
||||
|
||||
#include "AckStoreMap.h"
|
||||
|
||||
struct AckStoreMapIter;
|
||||
typedef struct AckStoreMapIter AckStoreMapIter;
|
||||
|
||||
static inline void AckStoreMapIter_init(AckStoreMapIter* this, AckStoreMap* map, RBTreeElem* treeElem);
|
||||
static inline AckStoreEntry* AckStoreMapIter_value(AckStoreMapIter* this);
|
||||
static inline bool AckStoreMapIter_end(AckStoreMapIter* this);
|
||||
|
||||
struct AckStoreMapIter
|
||||
{
|
||||
RBTreeIter rbTreeIter;
|
||||
};
|
||||
|
||||
void AckStoreMapIter_init(AckStoreMapIter* this, AckStoreMap* map, RBTreeElem* treeElem)
|
||||
{
|
||||
PointerRBTreeIter_init( (RBTreeIter*)this, (RBTree*)map, (RBTreeElem*)treeElem);
|
||||
}
|
||||
|
||||
AckStoreEntry* AckStoreMapIter_value(AckStoreMapIter* this)
|
||||
{
|
||||
return (AckStoreEntry*)PointerRBTreeIter_value( (RBTreeIter*)this);
|
||||
}
|
||||
|
||||
bool AckStoreMapIter_end(AckStoreMapIter* this)
|
||||
{
|
||||
return PointerRBTreeIter_end( (RBTreeIter*)this);
|
||||
}
|
||||
|
||||
|
||||
#endif /* ACKSTOREMAPITER_H_ */
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "AcknowledgmentStore.h"
|
||||
|
||||
/**
|
||||
* Note: This method does not lock the notifier->waitAcksMutex, because this is typically
|
||||
* called from a context that does not yet require syncing.
|
||||
*
|
||||
* @param waitAcks do not access this map until you called unregister (for thread-safety)
|
||||
* @param receivedAcks do not access this map until you called unregister (for thread-safety)
|
||||
* @param notifier used to wake up the thread waiting for acks
|
||||
*/
|
||||
void AcknowledgmentStore_registerWaitAcks(AcknowledgmentStore* this,
|
||||
WaitAckMap* waitAcks, WaitAckMap* receivedAcks, WaitAckNotification* notifier)
|
||||
{
|
||||
WaitAckMapIter iter;
|
||||
|
||||
Mutex_lock(&this->mutex);
|
||||
|
||||
for(iter = WaitAckMap_begin(waitAcks); !WaitAckMapIter_end(&iter); WaitAckMapIter_next(&iter) )
|
||||
{
|
||||
WaitAck* currentWaitAck = WaitAckMapIter_value(&iter);
|
||||
|
||||
AckStoreEntry* newStoreEntry = AckStoreEntry_construct(
|
||||
currentWaitAck->ackID, waitAcks, receivedAcks, notifier);
|
||||
|
||||
AckStoreMap_insert(&this->storeMap, currentWaitAck->ackID, newStoreEntry);
|
||||
}
|
||||
|
||||
Mutex_unlock(&this->mutex);
|
||||
}
|
||||
|
||||
void AcknowledgmentStore_unregisterWaitAcks(AcknowledgmentStore* this, WaitAckMap* waitAcks)
|
||||
{
|
||||
WaitAckMapIter iter;
|
||||
|
||||
Mutex_lock(&this->mutex);
|
||||
|
||||
for(iter = WaitAckMap_begin(waitAcks); !WaitAckMapIter_end(&iter); WaitAckMapIter_next(&iter) )
|
||||
{
|
||||
char* currentKey = WaitAckMapIter_key(&iter);
|
||||
AckStoreMapIter storeIter = AckStoreMap_find(&this->storeMap, currentKey);
|
||||
|
||||
// free allocated entry and remove it from store map
|
||||
|
||||
AckStoreEntry_destruct(AckStoreMapIter_value(&storeIter) );
|
||||
AckStoreMap_erase(&this->storeMap, currentKey);
|
||||
}
|
||||
|
||||
Mutex_unlock(&this->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if someone was waiting for this ackID, false otherwise
|
||||
*/
|
||||
bool AcknowledgmentStore_receivedAck(AcknowledgmentStore* this, const char* ackID)
|
||||
{
|
||||
bool retVal = false;
|
||||
AckStoreMapIter storeIter;
|
||||
|
||||
Mutex_lock(&this->mutex); // L O C K (store)
|
||||
|
||||
storeIter = AckStoreMap_find(&this->storeMap, ackID);
|
||||
if(!AckStoreMapIter_end(&storeIter) )
|
||||
{ // ack entry exists in store
|
||||
WaitAckMapIter waitIter;
|
||||
AckStoreEntry* storeEntry = AckStoreMapIter_value(&storeIter);
|
||||
|
||||
Mutex_lock(&storeEntry->notifier->waitAcksMutex); // L O C K (notifier)
|
||||
|
||||
waitIter = WaitAckMap_find(storeEntry->waitMap, ackID);
|
||||
if(!WaitAckMapIter_end(&waitIter) )
|
||||
{ // entry exists in waitMap => move to receivedMap
|
||||
char* waitAckID = WaitAckMapIter_key(&waitIter);
|
||||
WaitAck* waitAck = WaitAckMapIter_value(&waitIter);
|
||||
|
||||
WaitAckMap_insert(storeEntry->receivedMap, waitAckID, waitAck);
|
||||
WaitAckMap_erase(storeEntry->waitMap, ackID);
|
||||
|
||||
if(!WaitAckMap_length(storeEntry->waitMap) )
|
||||
{ // all acks received => notify
|
||||
WaitAckNotification* notifier = storeEntry->notifier;
|
||||
|
||||
Condition_broadcast(¬ifier->waitAcksCompleteCond);
|
||||
}
|
||||
|
||||
retVal = true;
|
||||
}
|
||||
|
||||
Mutex_unlock(&storeEntry->notifier->waitAcksMutex); // U N L O C K (notifier)
|
||||
|
||||
|
||||
AckStoreEntry_destruct(storeEntry);
|
||||
AckStoreMap_erase(&this->storeMap, ackID);
|
||||
}
|
||||
|
||||
Mutex_unlock(&this->mutex); // U N L O C K (store)
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
bool AcknowledgmentStore_waitForAckCompletion(AcknowledgmentStore* this,
|
||||
WaitAckMap* waitAcks, WaitAckNotification* notifier, int timeoutMS)
|
||||
{
|
||||
bool retVal;
|
||||
|
||||
Mutex_lock(¬ifier->waitAcksMutex);
|
||||
|
||||
if(WaitAckMap_length(waitAcks) )
|
||||
Condition_timedwait(¬ifier->waitAcksCompleteCond, ¬ifier->waitAcksMutex, timeoutMS);
|
||||
|
||||
retVal = WaitAckMap_length(waitAcks) ? false : true;
|
||||
|
||||
Mutex_unlock(¬ifier->waitAcksMutex);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef ACKNOWLEDGMENTSTORE_H_
|
||||
#define ACKNOWLEDGMENTSTORE_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <common/nodes/Node.h>
|
||||
#include <common/threading/Mutex.h>
|
||||
#include <common/threading/Condition.h>
|
||||
#include "AckStoreMap.h"
|
||||
#include "AckStoreMapIter.h"
|
||||
#include "WaitAckMap.h"
|
||||
#include "WaitAckMapIter.h"
|
||||
|
||||
|
||||
struct AcknowledgmentStore;
|
||||
typedef struct AcknowledgmentStore AcknowledgmentStore;
|
||||
|
||||
static inline void AcknowledgmentStore_init(AcknowledgmentStore* this);
|
||||
static inline AcknowledgmentStore* AcknowledgmentStore_construct(void);
|
||||
static inline void AcknowledgmentStore_uninit(AcknowledgmentStore* this);
|
||||
static inline void AcknowledgmentStore_destruct(AcknowledgmentStore* this);
|
||||
|
||||
extern void AcknowledgmentStore_registerWaitAcks(AcknowledgmentStore* this,
|
||||
WaitAckMap* waitAcks, WaitAckMap* receivedAcks, WaitAckNotification* notifier);
|
||||
extern void AcknowledgmentStore_unregisterWaitAcks(AcknowledgmentStore* this, WaitAckMap* waitAcks);
|
||||
extern bool AcknowledgmentStore_receivedAck(AcknowledgmentStore* this, const char* ackID);
|
||||
extern bool AcknowledgmentStore_waitForAckCompletion(AcknowledgmentStore* this,
|
||||
WaitAckMap* waitAcks, WaitAckNotification* notifier, int timeoutMS);
|
||||
|
||||
|
||||
|
||||
struct AcknowledgmentStore
|
||||
{
|
||||
AckStoreMap storeMap;
|
||||
Mutex mutex;
|
||||
};
|
||||
|
||||
|
||||
void AcknowledgmentStore_init(AcknowledgmentStore* this)
|
||||
{
|
||||
AckStoreMap_init(&this->storeMap);
|
||||
Mutex_init(&this->mutex);
|
||||
}
|
||||
|
||||
AcknowledgmentStore* AcknowledgmentStore_construct(void)
|
||||
{
|
||||
AcknowledgmentStore* this = (AcknowledgmentStore*)os_kmalloc(sizeof(*this) );
|
||||
|
||||
AcknowledgmentStore_init(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void AcknowledgmentStore_uninit(AcknowledgmentStore* this)
|
||||
{
|
||||
Mutex_uninit(&this->mutex);
|
||||
AckStoreMap_uninit(&this->storeMap);
|
||||
}
|
||||
|
||||
void AcknowledgmentStore_destruct(AcknowledgmentStore* this)
|
||||
{
|
||||
AcknowledgmentStore_uninit(this);
|
||||
|
||||
kfree(this);
|
||||
}
|
||||
|
||||
|
||||
#endif /* ACKNOWLEDGMENTSTORE_H_ */
|
||||
32
client_module/source/common/toolkit/ackstore/WaitAckMap.c
Normal file
32
client_module/source/common/toolkit/ackstore/WaitAckMap.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "WaitAckMap.h"
|
||||
#include "WaitAckMapIter.h"
|
||||
|
||||
WaitAckMapIter WaitAckMap_find(WaitAckMap* this, const char* searchKey)
|
||||
{
|
||||
RBTreeElem* treeElem = _PointerRBTree_findElem( (RBTree*)this, searchKey);
|
||||
|
||||
WaitAckMapIter iter;
|
||||
WaitAckMapIter_init(&iter, this, treeElem);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
WaitAckMapIter WaitAckMap_begin(WaitAckMap* this)
|
||||
{
|
||||
struct rb_node* node = rb_first(&this->rbTree.treeroot);
|
||||
RBTreeElem* treeElem = node ? container_of(node, RBTreeElem, treenode) : NULL;
|
||||
|
||||
WaitAckMapIter iter;
|
||||
WaitAckMapIter_init(&iter, this, treeElem);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
||||
int compareWaitAckMapElems(const void* key1, const void* key2)
|
||||
{
|
||||
return strcmp(key1, key2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
136
client_module/source/common/toolkit/ackstore/WaitAckMap.h
Normal file
136
client_module/source/common/toolkit/ackstore/WaitAckMap.h
Normal file
@@ -0,0 +1,136 @@
|
||||
#ifndef WAITACKMAP_H_
|
||||
#define WAITACKMAP_H_
|
||||
|
||||
#include <common/nodes/Node.h>
|
||||
#include <common/toolkit/tree/PointerRBTree.h>
|
||||
#include <common/toolkit/tree/PointerRBTreeIter.h>
|
||||
#include <common/threading/Mutex.h>
|
||||
#include <common/threading/Condition.h>
|
||||
|
||||
|
||||
struct WaitAckNotification;
|
||||
typedef struct WaitAckNotification WaitAckNotification;
|
||||
|
||||
struct WaitAck;
|
||||
typedef struct WaitAck WaitAck;
|
||||
|
||||
|
||||
struct WaitAckMapElem;
|
||||
typedef struct WaitAckMapElem WaitAckMapElem;
|
||||
struct WaitAckMap;
|
||||
typedef struct WaitAckMap WaitAckMap;
|
||||
|
||||
struct WaitAckMapIter; // forward declaration of the iterator
|
||||
|
||||
|
||||
static inline void WaitAckNotification_init(WaitAckNotification* this);
|
||||
static inline void WaitAckNotification_uninit(WaitAckNotification* this);
|
||||
|
||||
static inline void WaitAck_init(WaitAck* this, char* ackID, void* privateData);
|
||||
|
||||
|
||||
static inline void WaitAckMap_init(WaitAckMap* this);
|
||||
static inline void WaitAckMap_uninit(WaitAckMap* this);
|
||||
|
||||
static inline bool WaitAckMap_insert(WaitAckMap* this, char* newKey,
|
||||
WaitAck* newValue);
|
||||
static inline bool WaitAckMap_erase(WaitAckMap* this, const char* eraseKey);
|
||||
static inline size_t WaitAckMap_length(WaitAckMap* this);
|
||||
|
||||
static inline void WaitAckMap_clear(WaitAckMap* this);
|
||||
|
||||
extern struct WaitAckMapIter WaitAckMap_find(WaitAckMap* this, const char* searchKey);
|
||||
extern struct WaitAckMapIter WaitAckMap_begin(WaitAckMap* this);
|
||||
|
||||
extern int compareWaitAckMapElems(const void* key1, const void* key2);
|
||||
|
||||
|
||||
struct WaitAckNotification
|
||||
{
|
||||
Mutex waitAcksMutex; // this mutex also syncs access to the waitMap/receivedMap during the
|
||||
// wait phase (which is between registration and deregistration)
|
||||
Condition waitAcksCompleteCond; // in case all WaitAcks have been received
|
||||
};
|
||||
|
||||
struct WaitAck
|
||||
{
|
||||
char* ackID;
|
||||
void* privateData; // caller's private data
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct WaitAckMapElem
|
||||
{
|
||||
RBTreeElem rbTreeElem;
|
||||
};
|
||||
|
||||
struct WaitAckMap
|
||||
{
|
||||
RBTree rbTree;
|
||||
};
|
||||
|
||||
|
||||
void WaitAckNotification_init(WaitAckNotification* this)
|
||||
{
|
||||
Mutex_init(&this->waitAcksMutex);
|
||||
Condition_init(&this->waitAcksCompleteCond);
|
||||
}
|
||||
|
||||
void WaitAckNotification_uninit(WaitAckNotification* this)
|
||||
{
|
||||
Mutex_uninit(&this->waitAcksMutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ackID is not copied, so don't free or touch it while you use this object
|
||||
* @param privateData any private data that helps the caller to identify to ack later
|
||||
*/
|
||||
void WaitAck_init(WaitAck* this, char* ackID, void* privateData)
|
||||
{
|
||||
this->ackID = ackID;
|
||||
this->privateData = privateData;
|
||||
}
|
||||
|
||||
void WaitAckMap_init(WaitAckMap* this)
|
||||
{
|
||||
PointerRBTree_init( (RBTree*)this, compareWaitAckMapElems);
|
||||
}
|
||||
|
||||
void WaitAckMap_uninit(WaitAckMap* this)
|
||||
{
|
||||
PointerRBTree_uninit( (RBTree*)this);
|
||||
}
|
||||
|
||||
|
||||
bool WaitAckMap_insert(WaitAckMap* this, char* newKey, WaitAck* newValue)
|
||||
{
|
||||
bool insRes;
|
||||
|
||||
insRes = PointerRBTree_insert( (RBTree*)this, newKey, newValue);
|
||||
if(!insRes)
|
||||
{
|
||||
// not inserted because the key already existed
|
||||
}
|
||||
|
||||
return insRes;
|
||||
}
|
||||
|
||||
bool WaitAckMap_erase(WaitAckMap* this, const char* eraseKey)
|
||||
{
|
||||
return PointerRBTree_erase( (RBTree*)this, eraseKey);
|
||||
}
|
||||
|
||||
size_t WaitAckMap_length(WaitAckMap* this)
|
||||
{
|
||||
return PointerRBTree_length( (RBTree*)this);
|
||||
}
|
||||
|
||||
|
||||
void WaitAckMap_clear(WaitAckMap* this)
|
||||
{
|
||||
PointerRBTree_clear(&this->rbTree);
|
||||
}
|
||||
|
||||
|
||||
#endif /* WAITACKMAP_H_ */
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef WAITACKMAPITER_H_
|
||||
#define WAITACKMAPITER_H_
|
||||
|
||||
#include "WaitAckMap.h"
|
||||
|
||||
struct WaitAckMapIter;
|
||||
typedef struct WaitAckMapIter WaitAckMapIter;
|
||||
|
||||
static inline void WaitAckMapIter_init(WaitAckMapIter* this, WaitAckMap* map, RBTreeElem* treeElem);
|
||||
static inline WaitAck* WaitAckMapIter_next(WaitAckMapIter* this);
|
||||
static inline char* WaitAckMapIter_key(WaitAckMapIter* this);
|
||||
static inline WaitAck* WaitAckMapIter_value(WaitAckMapIter* this);
|
||||
static inline bool WaitAckMapIter_end(WaitAckMapIter* this);
|
||||
|
||||
struct WaitAckMapIter
|
||||
{
|
||||
RBTreeIter rbTreeIter;
|
||||
};
|
||||
|
||||
void WaitAckMapIter_init(WaitAckMapIter* this, WaitAckMap* map, RBTreeElem* treeElem)
|
||||
{
|
||||
PointerRBTreeIter_init( (RBTreeIter*)this, (RBTree*)map, (RBTreeElem*)treeElem);
|
||||
}
|
||||
|
||||
WaitAck* WaitAckMapIter_next(WaitAckMapIter* this)
|
||||
{
|
||||
return (WaitAck*)PointerRBTreeIter_next( (RBTreeIter*)this);
|
||||
}
|
||||
|
||||
char* WaitAckMapIter_key(WaitAckMapIter* this)
|
||||
{
|
||||
return (char*)PointerRBTreeIter_key( (RBTreeIter*)this);
|
||||
}
|
||||
|
||||
WaitAck* WaitAckMapIter_value(WaitAckMapIter* this)
|
||||
{
|
||||
return (WaitAck*)PointerRBTreeIter_value( (RBTreeIter*)this);
|
||||
}
|
||||
|
||||
bool WaitAckMapIter_end(WaitAckMapIter* this)
|
||||
{
|
||||
return PointerRBTreeIter_end( (RBTreeIter*)this);
|
||||
}
|
||||
|
||||
|
||||
#endif /* WAITACKMAPITER_H_ */
|
||||
Reference in New Issue
Block a user