137 lines
3.9 KiB
C++
137 lines
3.9 KiB
C++
#include "RequestTable.h"
|
|
|
|
|
|
RequestTable::RequestTable ( ) {
|
|
m_bufSize = 2 * HT_BUF_SIZE;
|
|
//m_htable.set ( 50 , m_buf, m_bufSize, true ); // allow dup keys?
|
|
m_processHash = 0;
|
|
}
|
|
|
|
RequestTable::~RequestTable ( ) {
|
|
reset();
|
|
}
|
|
|
|
void RequestTable::reset ( ) {
|
|
m_htable.reset();
|
|
m_processHash = 0;
|
|
}
|
|
|
|
int32_t RequestTable::addRequest ( int64_t requestHash , void *state2 ) {
|
|
// sanity check
|
|
if ( requestHash == 0 ){
|
|
char *xx = NULL; *xx = 0;
|
|
}
|
|
|
|
if ( m_htable.m_ks == 0 ) {
|
|
//HashTableT <int64_t,int32_t> m_htable;
|
|
// allow dups!
|
|
m_htable.set(8,sizeof(char *),50,m_buf,m_bufSize,
|
|
true,0,"rqstbl");
|
|
}
|
|
|
|
// check if we have the state already in the hashtable
|
|
/*int32_t n = m_htable.getSlot ( requestHash );
|
|
while ( m_htable.m_keys[n] ){
|
|
// count if same key
|
|
if ( m_htable.m_keys[n] == requestHash &&
|
|
m_htable.m_vals[n] == ( int32_t ) state2 ){
|
|
char *xx = NULL; *xx = 0;
|
|
}
|
|
// advance n, wrapping if necessary
|
|
if ( ++n >= m_htable.m_numSlots ) n = 0;
|
|
}*/
|
|
|
|
// returns false and set g_errno on error, so we should return -1
|
|
if ( ! m_htable.addKey(&requestHash, &state2) ) return -1;
|
|
|
|
//log ( "requesttable: added hash=%"INT64" state2=%"XINT32"", requestHash,
|
|
// (int32_t) state2 );
|
|
// count the slots that have this key
|
|
int32_t n = m_htable.getSlot ( &requestHash );
|
|
// sanity check
|
|
if ( n < 0 ) { char *xx = NULL; *xx = 0; }
|
|
|
|
// return more than 1 if we are processing the same hash in gotReply
|
|
// gotReply shall call it eventually so no need to send udpServer
|
|
if ( m_processHash == requestHash )
|
|
return 2;
|
|
|
|
// count how many of our key are in the table, since we allow dup keys
|
|
int32_t count = 0;
|
|
|
|
while ( m_htable.m_flags[n]) { // m_keys[n] ){
|
|
// count if same key
|
|
if ( *(int64_t *)m_htable.getValueFromSlot(n) == requestHash )
|
|
count++;
|
|
// advance n, wrapping if necessary
|
|
if ( ++n >= m_htable.m_numSlots ) n = 0;
|
|
}
|
|
/*if ( count == 1 )
|
|
log( "requesttable: hash=%"INT64" state2=%"XINT32" is getting quality",
|
|
requestHash, (int32_t) state2 );*/
|
|
return count;
|
|
}
|
|
|
|
void RequestTable::gotReply ( int64_t requestHash ,
|
|
char *reply ,
|
|
int32_t replySize ,
|
|
void *state1 ,
|
|
void (*callback)( char *reply ,
|
|
int32_t replySize ,
|
|
void *state1 ,
|
|
void *state2 )){
|
|
// sanity check.
|
|
// We should never get a call when we are processing the request.
|
|
if ( m_processHash != 0 ){
|
|
char *xx = NULL; *xx = 0;
|
|
}
|
|
// lock the hashtable by adding the current key
|
|
m_processHash = requestHash;
|
|
|
|
// save g_errno in case callback resets it
|
|
int32_t saved = g_errno;
|
|
int32_t n = m_htable.getSlot ( &requestHash );
|
|
while ( n >= 0 ) {
|
|
// restore it before returning
|
|
g_errno = saved;
|
|
|
|
// state2 is in the table
|
|
//void *state2 = (void *)m_htable.m_vals[n];
|
|
void *state2 = *(void **)m_htable.getValueFromSlot(n);
|
|
// remove from table BEFORE calling callback in case callback
|
|
// somehow alters the table!
|
|
//m_htable.removeKey ( requestHash );
|
|
m_htable.removeSlot ( n );
|
|
/*log ( "requesttable: removed hash=%"INT64" state1=%"XINT32" state2=%"XINT32"",
|
|
requestHash, (int32_t) state1, (int32_t) state2 );*/
|
|
|
|
// restore it before calling callback
|
|
g_errno = saved;
|
|
// otherwise, it is, call callback
|
|
callback ( reply , replySize , state1 , state2 );
|
|
// get next
|
|
n = m_htable.getSlot ( &requestHash );
|
|
}
|
|
// all done, unlock the hash table.
|
|
m_processHash = 0;
|
|
return;
|
|
}
|
|
|
|
void RequestTable::cancelRequest ( int64_t requestHash , void *state2 ) {
|
|
// there should only be one request for this request hash
|
|
int32_t n = m_htable.getSlot ( &requestHash );
|
|
if ( n < 0 ){
|
|
char *xx = NULL; *xx = 0;
|
|
}
|
|
m_htable.removeKey(&requestHash);
|
|
// check if there is any other remaining. core if there is
|
|
n = m_htable.getSlot ( &requestHash );
|
|
if ( n >= 0 ){
|
|
char *xx = NULL; *xx = 0;
|
|
}
|
|
log( LOG_INFO, "reqtable: cancelled "
|
|
"request hash=%" INT64 " state2=%" PTRFMT "",
|
|
requestHash, (PTRTYPE) state2 );
|
|
return;
|
|
}
|