commit
3b65b25541
|
@ -21,15 +21,42 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
int taosOpenRef(int max, void (*fp)(void *)); // return refId which will be used by other APIs
|
||||
void taosCloseRef(int refId);
|
||||
int taosListRef(); // return the number of references in system
|
||||
int taosAddRef(int refId, void *p);
|
||||
int taosAcquireRef(int refId, void *p);
|
||||
void taosReleaseRef(int refId, void *p);
|
||||
// open an instance, return refId which will be used by other APIs
|
||||
int taosOpenRef(int max, void (*fp)(void *));
|
||||
|
||||
// close the Ref instance
|
||||
void taosCloseRef(int refId);
|
||||
|
||||
// add ref, p is the pointer to resource or pointer ID
|
||||
int taosAddRef(int refId, void *p);
|
||||
#define taosRemoveRef taosReleaseRef
|
||||
|
||||
// acquire ref, p is the pointer to resource or pointer ID
|
||||
int taosAcquireRef(int refId, void *p);
|
||||
|
||||
// release ref, p is the pointer to resource or pinter ID
|
||||
void taosReleaseRef(int refId, void *p);
|
||||
|
||||
// return the first if p is null, otherwise return the next after p
|
||||
void *taosIterateRef(int refId, void *p);
|
||||
|
||||
// return the number of references in system
|
||||
int taosListRef();
|
||||
|
||||
/* sample code to iterate the refs
|
||||
|
||||
void demoIterateRefs(int refId) {
|
||||
|
||||
void *p = taosIterateRef(refId, NULL);
|
||||
while (p) {
|
||||
|
||||
// process P
|
||||
|
||||
p = taosIterateRef(refId, p);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -143,8 +143,6 @@ int taosAddRef(int refId, void *p)
|
|||
return TSDB_CODE_REF_INVALID_ID;
|
||||
}
|
||||
|
||||
uTrace("refId:%d p:%p try to add", refId, p);
|
||||
|
||||
pSet = tsRefSetList + refId;
|
||||
taosIncRefCount(pSet);
|
||||
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
||||
|
@ -203,8 +201,6 @@ int taosAcquireRef(int refId, void *p)
|
|||
return TSDB_CODE_REF_INVALID_ID;
|
||||
}
|
||||
|
||||
uTrace("refId:%d p:%p try to acquire", refId, p);
|
||||
|
||||
pSet = tsRefSetList + refId;
|
||||
taosIncRefCount(pSet);
|
||||
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
||||
|
@ -254,8 +250,6 @@ void taosReleaseRef(int refId, void *p)
|
|||
return;
|
||||
}
|
||||
|
||||
uTrace("refId:%d p:%p try to release", refId, p);
|
||||
|
||||
pSet = tsRefSetList + refId;
|
||||
if (pSet->state == TSDB_REF_STATE_EMPTY) {
|
||||
uTrace("refId:%d p:%p failed to release, cleaned", refId, p);
|
||||
|
@ -305,6 +299,75 @@ void taosReleaseRef(int refId, void *p)
|
|||
if (released) taosDecRefCount(pSet);
|
||||
}
|
||||
|
||||
// if p is NULL, return the first p in hash list, otherwise, return the next after p
|
||||
void *taosIterateRef(int refId, void *p) {
|
||||
SRefNode *pNode = NULL;
|
||||
SRefSet *pSet;
|
||||
|
||||
if (refId < 0 || refId >= TSDB_REF_OBJECTS) {
|
||||
uTrace("refId:%d p:%p failed to iterate, refId not valid", refId, p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSet = tsRefSetList + refId;
|
||||
taosIncRefCount(pSet);
|
||||
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
||||
uTrace("refId:%d p:%p failed to iterate, not active", refId, p);
|
||||
taosDecRefCount(pSet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hash = 0;
|
||||
if (p) {
|
||||
hash = taosHashRef(pSet, p);
|
||||
taosLockList(pSet->lockedBy+hash);
|
||||
|
||||
pNode = pSet->nodeList[hash];
|
||||
while (pNode) {
|
||||
if (pNode->p == p) break;
|
||||
pNode = pNode->next;
|
||||
}
|
||||
|
||||
if (pNode == NULL) {
|
||||
uError("refId:%d p:%p not there, quit", refId, p);
|
||||
taosUnlockList(pSet->lockedBy+hash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// p is there
|
||||
pNode = pNode->next;
|
||||
if (pNode == NULL) {
|
||||
taosUnlockList(pSet->lockedBy+hash);
|
||||
hash++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pNode == NULL) {
|
||||
for (; hash < pSet->max; ++hash) {
|
||||
taosLockList(pSet->lockedBy+hash);
|
||||
pNode = pSet->nodeList[hash];
|
||||
if (pNode) break;
|
||||
taosUnlockList(pSet->lockedBy+hash);
|
||||
}
|
||||
}
|
||||
|
||||
void *newP = NULL;
|
||||
if (pNode) {
|
||||
pNode->count++; // acquire it
|
||||
newP = pNode->p;
|
||||
taosUnlockList(pSet->lockedBy+hash);
|
||||
uTrace("refId:%d p:%p is returned", refId, p);
|
||||
} else {
|
||||
uTrace("refId:%d p:%p the list is over", refId, p);
|
||||
}
|
||||
|
||||
if (p) taosReleaseRef(refId, p); // release the current one
|
||||
|
||||
taosDecRefCount(pSet);
|
||||
|
||||
return newP;
|
||||
}
|
||||
|
||||
int taosListRef() {
|
||||
SRefSet *pSet;
|
||||
SRefNode *pNode;
|
||||
|
|
|
@ -17,6 +17,19 @@ typedef struct {
|
|||
void **p;
|
||||
} SRefSpace;
|
||||
|
||||
void iterateRefs(int refId) {
|
||||
int count = 0;
|
||||
|
||||
void *p = taosIterateRef(refId, NULL);
|
||||
while (p) {
|
||||
// process P
|
||||
count++;
|
||||
p = taosIterateRef(refId, p);
|
||||
}
|
||||
|
||||
printf(" %d ", count);
|
||||
}
|
||||
|
||||
void *takeRefActions(void *param) {
|
||||
SRefSpace *pSpace = (SRefSpace *)param;
|
||||
int code, id;
|
||||
|
@ -44,6 +57,9 @@ void *takeRefActions(void *param) {
|
|||
usleep(id % 5 + 1);
|
||||
taosReleaseRef(pSpace->refId, pSpace->p[id]);
|
||||
}
|
||||
|
||||
id = random() % pSpace->refNum;
|
||||
iterateRefs(id);
|
||||
}
|
||||
|
||||
for (int i=0; i < pSpace->refNum; ++i) {
|
||||
|
@ -63,7 +79,7 @@ void *openRefSpace(void *param) {
|
|||
SRefSpace *pSpace = (SRefSpace *)param;
|
||||
|
||||
printf("c");
|
||||
pSpace->refId = taosOpenRef(10000, myfree);
|
||||
pSpace->refId = taosOpenRef(50, myfree);
|
||||
|
||||
if (pSpace->refId < 0) {
|
||||
printf("failed to open ref, reson:%s\n", tstrerror(pSpace->refId));
|
||||
|
|
Loading…
Reference in New Issue