struct WHOQueueEntry *next;
void *callback[MAXCALLBACKS];
void *data[MAXCALLBACKS];
- #ifdef HAVE_THREADS
- unsigned long lock_tid;
- pthread_mutex_t lock_mutex;
- int lock_count;
- #endif
};
+#ifdef HAVE_THREADS
+struct ParseOrder {
+ unsigned long tid;
+ struct ParseOrder *next;
+};
+struct ParseOrder *parse_order = NULL;
+#endif
+
static int checkWHOID(struct ClientSocket *client, int whoid) {
struct WHOQueueEntry *entry;
for(entry = client->whoqueue_first; entry; entry = entry->next) {
}
entry->next = NULL;
entry->whoid = whoid;
- #ifdef HAVE_THREADS
- entry->lock_tid = 0;
- THREAD_MUTEX_INIT(entry->lock_mutex);
- entry->lock_count = 0;
- #endif
if(client->whoqueue_last) {
client->whoqueue_last->next = entry;
} else {
if(entry == client->whoqueue_last) {
client->whoqueue_last = NULL;
}
- #ifdef HAVE_THREADS
- entry->lock_tid = -1;
- if(entry->lock_count) {
- int i;
- for(i = 0; i < entry->lock_count; i++) {
- DESYNCHRONIZE(entry->lock_mutex); //unlock ALL
- }
- }
- #endif
}
DESYNCHRONIZE(whohandler_sync);
return entry;
struct WHOQueueEntry *entry, *next;
for(entry = client->whoqueue_first; entry; entry = next) {
next = entry->next;
- #ifdef HAVE_THREADS
- entry->lock_tid = -1;
- if(entry->lock_count) {
- int i;
- for(i = 0; i < entry->lock_count; i++) {
- DESYNCHRONIZE(entry->lock_mutex); //unlock ALL
- }
- }
- #endif
free(entry);
}
client->whoqueue_last = NULL;
}
#if HAVE_THREADS
-void whohandler_end_of_recv(struct ClientSocket *client) {
+void whohandler_start_of_recv(struct ClientSocket *client, unsigned long tid) {
SYNCHRONIZE(whohandler_sync);
- unsigned long tid = syscall(SYS_gettid);
- struct WHOQueueEntry *entry;
- for(entry = client->whoqueue_first; entry; entry = entry->next) {
- if(entry->lock_tid == tid) {
- entry->lock_tid = 0;
- DESYNCHRONIZE(entry->lock_mutex);
- }
+ struct ParseOrder *entry, *last;
+ for(last = parse_order; last; last = last->next) {
+ if(last->next == NULL)
+ break;
+ }
+ entry = malloc(sizeof(*entry));
+ entry->tid = tid;
+ entry->next = NULL;
+ if(last)
+ last->next = entry;
+ else
+ parse_order = entry;
+ DESYNCHRONIZE(whohandler_sync);
+}
+
+void whohandler_end_of_recv(struct ClientSocket *client, unsigned long tid) {
+ SYNCHRONIZE(whohandler_sync);
+ struct ParseOrder *entry, *last = NULL;
+ for(entry = parse_order; entry; entry = entry->next) {
+ if(entry->tid == tid) {
+ if(last)
+ last->next = entry->next;
+ else
+ parse_order = entry->next;
+ free(entry);
+ break;
+ } else
+ last = entry;
}
DESYNCHRONIZE(whohandler_sync);
}
if(entry == NULL) return;
#ifdef HAVE_THREADS
unsigned long tid = syscall(SYS_gettid);
- if(entry->lock_tid != tid) {
- entry->lock_count++;
- SYNCHRONIZE(entry->lock_mutex);
- if(entry->lock_tid == -1) {
- return; //entry has been destroyed
- }
- entry->lock_tid = tid;
+ while(parse_order->tid != tid) {
+ usleep(5000); //5ms
}
#endif
if(entry->type & WHOQUEUETYPE_USERLIST) {
if(entry == NULL) return;
#ifdef HAVE_THREADS
unsigned long tid = syscall(SYS_gettid);
- if(entry->lock_tid != tid) {
- entry->lock_count++;
- SYNCHRONIZE(entry->lock_mutex);
- if(entry->lock_tid == -1) {
- return; //entry has been destroyed
- }
- entry->lock_tid = tid;
+ while(parse_order->tid != tid) {
+ usleep(5000); //5ms
}
#endif
getNextWHOQueueEntry(client, type, 1);