1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
#ifndef LOCKS_H
#define LOCKS_H
#include <stdint.h>
#include <sys/time.h>
/* This application uses several double linked lists.
* They are circular lists, new items are added on the end (ie. on prev)
* and popped from next.
*/
struct double_linked_list {
struct double_linked_list* prev;
struct double_linked_list* next;
};
struct hashtable_entry {
struct double_linked_list hashtable_siblings;
struct hashtable* parent_hashtable;
uint32_t key_hash;
char* key;
};
struct PoolCounter {
struct hashtable_entry htentry;
uint32_t count;
int processing;
struct double_linked_list working;
struct double_linked_list for_them;
struct double_linked_list for_anyone;
};
enum lock_state {
LS_UNLOCKED, // Not yet locked or already unlocked
LS_WAITING, // Waiting on ACQ4ME
LS_WAIT_ANY, // Waiting on ACQ4ANY
LS_PROCESSING, // Currently locked
};
struct locks {
/*
* Siblings in whatever linked list this lives. Either working, for_them
* or for_anyone.
*/
struct double_linked_list siblings;
struct PoolCounter* parent;
enum lock_state state;
/*
* Instant where is started waiting/processing.
*/
struct timeval timeval;
/**
* Pointer back to client_data needed when pulling the lock from one of the
* linked lists.
*/
void* client_data;
};
struct client_data;
void finish_lock(struct locks* l);
const char* process_line(struct client_data* cli_data, char* line, int line_len);
void remove_client_lock(struct locks* l, int wakeup_anyones);
void hashtable_init();
struct hashtable* hashtable_create(int hashpower);
void* hashtable_find(struct hashtable* ht, uint32_t hash_value, const char* key);
void hashtable_insert(struct hashtable* ht, struct hashtable_entry* htentry);
void hashtable_remove(struct hashtable* ht, struct hashtable_entry* htentry);
#endif
|