commit
3b65b25541
|
@ -21,15 +21,42 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int taosOpenRef(int max, void (*fp)(void *)); // return refId which will be used by other APIs
|
// open an instance, return refId which will be used by other APIs
|
||||||
void taosCloseRef(int refId);
|
int taosOpenRef(int max, void (*fp)(void *));
|
||||||
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);
|
|
||||||
|
|
||||||
|
// 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
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,8 +143,6 @@ int taosAddRef(int refId, void *p)
|
||||||
return TSDB_CODE_REF_INVALID_ID;
|
return TSDB_CODE_REF_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
uTrace("refId:%d p:%p try to add", refId, p);
|
|
||||||
|
|
||||||
pSet = tsRefSetList + refId;
|
pSet = tsRefSetList + refId;
|
||||||
taosIncRefCount(pSet);
|
taosIncRefCount(pSet);
|
||||||
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
||||||
|
@ -203,8 +201,6 @@ int taosAcquireRef(int refId, void *p)
|
||||||
return TSDB_CODE_REF_INVALID_ID;
|
return TSDB_CODE_REF_INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
uTrace("refId:%d p:%p try to acquire", refId, p);
|
|
||||||
|
|
||||||
pSet = tsRefSetList + refId;
|
pSet = tsRefSetList + refId;
|
||||||
taosIncRefCount(pSet);
|
taosIncRefCount(pSet);
|
||||||
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
|
||||||
|
@ -254,8 +250,6 @@ void taosReleaseRef(int refId, void *p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uTrace("refId:%d p:%p try to release", refId, p);
|
|
||||||
|
|
||||||
pSet = tsRefSetList + refId;
|
pSet = tsRefSetList + refId;
|
||||||
if (pSet->state == TSDB_REF_STATE_EMPTY) {
|
if (pSet->state == TSDB_REF_STATE_EMPTY) {
|
||||||
uTrace("refId:%d p:%p failed to release, cleaned", refId, p);
|
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 (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() {
|
int taosListRef() {
|
||||||
SRefSet *pSet;
|
SRefSet *pSet;
|
||||||
SRefNode *pNode;
|
SRefNode *pNode;
|
||||||
|
|
|
@ -17,6 +17,19 @@ typedef struct {
|
||||||
void **p;
|
void **p;
|
||||||
} SRefSpace;
|
} 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) {
|
void *takeRefActions(void *param) {
|
||||||
SRefSpace *pSpace = (SRefSpace *)param;
|
SRefSpace *pSpace = (SRefSpace *)param;
|
||||||
int code, id;
|
int code, id;
|
||||||
|
@ -44,6 +57,9 @@ void *takeRefActions(void *param) {
|
||||||
usleep(id % 5 + 1);
|
usleep(id % 5 + 1);
|
||||||
taosReleaseRef(pSpace->refId, pSpace->p[id]);
|
taosReleaseRef(pSpace->refId, pSpace->p[id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id = random() % pSpace->refNum;
|
||||||
|
iterateRefs(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i < pSpace->refNum; ++i) {
|
for (int i=0; i < pSpace->refNum; ++i) {
|
||||||
|
@ -63,7 +79,7 @@ void *openRefSpace(void *param) {
|
||||||
SRefSpace *pSpace = (SRefSpace *)param;
|
SRefSpace *pSpace = (SRefSpace *)param;
|
||||||
|
|
||||||
printf("c");
|
printf("c");
|
||||||
pSpace->refId = taosOpenRef(10000, myfree);
|
pSpace->refId = taosOpenRef(50, myfree);
|
||||||
|
|
||||||
if (pSpace->refId < 0) {
|
if (pSpace->refId < 0) {
|
||||||
printf("failed to open ref, reson:%s\n", tstrerror(pSpace->refId));
|
printf("failed to open ref, reson:%s\n", tstrerror(pSpace->refId));
|
||||||
|
|
Loading…
Reference in New Issue