Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Anomap, Rewrite discord-refcount.c #172

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
805 changes: 713 additions & 92 deletions core/anomap.c

Large diffs are not rendered by default.

122 changes: 99 additions & 23 deletions core/anomap.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,58 +10,134 @@
#include <stddef.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

#define ANOMAP_DECLARE_COMPARE_FUNCTION(function_name, data_type) \
static int \
function_name(const void *a, const void *b) { \
if (*(data_type *)a == *(data_type *)b) return 0; \
return *(data_type *)a > *(data_type *)b ? 1 : -1; \
}

enum anomap_operation {
anomap_insert = 1 << 0,
anomap_update = 1 << 1,
anomap_upsert = anomap_insert | anomap_update,
anomap_delete = 1 << 2,
anomap_getval = 1 << 3,
};
typedef enum {
#define ANOMAP_REVERSE_ORDER anomap_reverse_order
anomap_reverse_order = 1 << 0,

#define ANOMAP_DIRECT_ACCESS anomap_direct_access
anomap_direct_access = 1 << 1,

#define ANOMAP_PRESERVE_ORDER anomap_preserve_order
anomap_preserve_order = 1 << 2,

#define ANOMAP_USE_LOCK anomap_use_lock
anomap_use_lock = 1 << 3,
} anomap_options;

typedef enum {
#define ANOMAP_INSERT anomap_insert
anomap_insert = 1 << 0,

#define ANOMAP_UPDATE anomap_update
anomap_update = 1 << 1,

#define ANOMAP_UPSERT anomap_upsert
anomap_upsert = anomap_insert | anomap_update,

#define ANOMAP_DELETE anomap_delete
anomap_delete = 1 << 2,

#define ANOMAP_GETVAL anomap_getval
anomap_getval = 1 << 3,
} anomap_operation;

typedef struct anomap anomap;

anomap_options anomap_supported_options(void);

struct anomap;
size_t anomap_struct_size(void);

struct anomap *anomap_create(size_t key_size, size_t val_size,
int (*cmp)(const void *, const void *));
void anomap_destroy(struct anomap *map);
bool anomap_init(anomap *map,
size_t key_size, size_t val_size,
int (*cmp)(const void *, const void *),
anomap_options options);

anomap *anomap_create(size_t key_size, size_t val_size,
int (*cmp)(const void *, const void *),
anomap_options options);
void anomap_destroy(anomap *map);

typedef enum {
#define ANOMAP_CLONE_OPTIONS_NONE anomap_clone_options_none
anomap_clone_options_none,
} anomap_clone_options;

struct anomap *anomap_clone(anomap *map, anomap_clone_options options);
void anomap_move(anomap *dest, bool free_on_destroy, anomap *map);

struct anomap_item_changed {
struct anomap *map;
void *data;
enum anomap_operation op;
anomap_operation op;
void *key;
struct {
void *prev;
void *now;
} val;
};

typedef void anomap_on_item_changed(
struct anomap *map, struct anomap_item_changed *item_changed);
typedef void anomap_on_item_changed(const struct anomap_item_changed *ev);

void anomap_set_on_item_changed(
struct anomap *map, anomap_on_item_changed *on_changed, void *data);

size_t anomap_length(struct anomap *map);
void anomap_clear(struct anomap *map);
size_t anomap_length(anomap *map);
void anomap_clear(anomap *map);

bool anomap_index_of(struct anomap *map, void *key, size_t *index);
bool anomap_at_index(struct anomap *map, size_t index, void *key, void *val);
bool anomap_contains(anomap *map, void *key);
bool anomap_index_of(anomap *map, void *key, size_t *index);
bool anomap_at_index(anomap *map, size_t index, void *key, void *val);
const void *anomap_direct_key_at_index(anomap *map, size_t index);
void *anomap_direct_val_at_index(anomap *map, size_t index);

enum anomap_operation anomap_do(struct anomap *map,
enum anomap_operation operation,
void *key, void *val);
anomap_operation anomap_do(anomap *map,
anomap_operation operation,
void *key, void *val);

size_t anomap_copy_range(struct anomap *map,
size_t anomap_copy_range(anomap *map,
size_t from_index, size_t to_index,
void *keys, void *vals);
size_t anomap_delete_range(struct anomap *map,
size_t anomap_delete_range(anomap *map,
size_t from_index, size_t to_index,
void *keys, void *vals);

typedef void anomap_foreach_cb(const void *key, const void *val, void *data);
void anomap_foreach(anomap *map, anomap_foreach_cb *cb, void *data);
void anomap_foreach_reverse(anomap *map, anomap_foreach_cb *cb, void *data);

typedef enum {
#define ANOMAP_HEAD anomap_head
anomap_head,

#define ANOMAP_TAIL anomap_tail
anomap_tail,

#define ANOMAP_PREV anomap_prev
anomap_prev,

#define ANOMAP_NEXT anomap_next
anomap_next,
} anomap_position;

bool anomap_advance(anomap *map,
size_t *index,
anomap_position *position);

int anomap_cmp_str(const void *a, const void *b);

#ifdef __cplusplus
}
#endif

#endif // !ANOMAP_H
34 changes: 24 additions & 10 deletions core/io_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <string.h>
#include <inttypes.h>
#include <time.h>
#include <sys/ioctl.h>

#ifndef __MINGW32__
#include <poll.h>
Expand Down Expand Up @@ -49,7 +50,7 @@ on_io_poller_wakeup(struct io_poller *io,
enum io_poller_events events,
void *user_data)
{
char buf[0x10000];
char buf[0x1000];
(void)!read(io->wakeup_fds[0], buf, sizeof buf);
}

Expand All @@ -63,14 +64,23 @@ io_poller_create(void)
io->pollfds = calloc(io->cap, sizeof *io->pollfds);
if (io->elements && io->pollfds) {
if (0 == pipe(io->wakeup_fds)) {
int flags = fcntl(io->wakeup_fds[0], F_GETFL);
fcntl(io->wakeup_fds[0], F_SETFL, flags | O_NONBLOCK);
flags = fcntl(io->wakeup_fds[1], F_GETFL);
fcntl(io->wakeup_fds[1], F_SETFL, flags | O_NONBLOCK);

io_poller_socket_add(io, io->wakeup_fds[0], IO_POLLER_IN,
on_io_poller_wakeup, NULL);
return io;
bool success = true;
for (int i = 0; i < 2; i++) {
int flags = fcntl(io->wakeup_fds[i], F_GETFL) | O_NONBLOCK;
if (0 != fcntl(io->wakeup_fds[i], F_SETFL, flags))
success = false;
#ifdef FIOCLEX
if (0 != ioctl(io->wakeup_fds[i], FIOCLEX, NULL))
success = false;
#endif
}
if (success) {
io_poller_socket_add(io, io->wakeup_fds[0], IO_POLLER_IN,
on_io_poller_wakeup, NULL);
return io;
}
close(io->wakeup_fds[1]);
close(io->wakeup_fds[0]);
}
}
free(io->elements);
Expand Down Expand Up @@ -130,6 +140,8 @@ io_poller_perform(struct io_poller *io)
int events = 0;
if (io->pollfds[i].revents & POLLIN) events |= IO_POLLER_IN;
if (io->pollfds[i].revents & POLLOUT) events |= IO_POLLER_OUT;
if (io->pollfds[i].revents & POLLPRI) events |= IO_POLLER_PRI;
if (io->pollfds[i].revents & POLLERR) events |= IO_POLLER_ERR;
io->pollfds[i].revents = 0;
struct io_poller_element *element = &io->elements[i];
element->cb(io, events, element->user_data);
Expand All @@ -138,7 +150,8 @@ io_poller_perform(struct io_poller *io)
for (int i = 0; i < io->curlm_cnt; i++) {
struct io_curlm *curlm = io->curlm[i];
if (curlm->should_perform
|| (-1 != curlm->timeout && now >= curlm->timeout)) {
|| (-1 != curlm->timeout && now >= curlm->timeout))
{
curlm->should_perform = false;
int result =
curlm->cb
Expand Down Expand Up @@ -188,6 +201,7 @@ io_poller_socket_add(struct io_poller *io,
io->pollfds[index].events = 0;
if (events & IO_POLLER_IN) io->pollfds[index].events |= POLLIN;
if (events & IO_POLLER_OUT) io->pollfds[index].events |= POLLOUT;
if (events & IO_POLLER_PRI) io->pollfds[index].events |= POLLPRI;
io->elements[index].cb = cb;
io->elements[index].user_data = user_data;
return true;
Expand Down
2 changes: 2 additions & 0 deletions core/io_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
enum io_poller_events {
IO_POLLER_IN = 1 << 0,
IO_POLLER_OUT = 1 << 1,
IO_POLLER_PRI = 1 << 2,
IO_POLLER_ERR = 1 << 3,
};

/**
Expand Down
50 changes: 26 additions & 24 deletions include/discord-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern "C" {
#include "queue.h"
#include "priority_queue.h"
#include "attributes.h"
#include "anomap.h"

/** @brief Return 1 if string isn't considered empty */
#define NOT_EMPTY_STR(str) ((str) && *(str))
Expand Down Expand Up @@ -493,7 +494,7 @@ struct discord_requestor {
* their callbacks to be called from the main thread
*/
QUEUE(struct discord_request) finished;
} * queues;
} *queues;

/** queue locks */
struct {
Expand All @@ -503,7 +504,7 @@ struct discord_requestor {
pthread_mutex_t pending;
/** finished queue lock */
pthread_mutex_t finished;
} * qlocks;
} *qlocks;
};

/**
Expand Down Expand Up @@ -780,7 +781,7 @@ struct discord_gateway {
int ping_ms;
/** ping rwlock */
pthread_rwlock_t rwlock;
} * timer;
} *timer;

/** the identify structure for client authentication */
struct discord_identify id;
Expand Down Expand Up @@ -938,17 +939,9 @@ void discord_gateway_dispatch(struct discord_gateway *gw);
struct discord_refcounter {
/** `DISCORD_REFCOUNT` logging module */
struct logconf conf;
/** amount of individual user's data held for automatic cleanup */
int length;
/** cap before increase */
int capacity;
/**
* individual user's data held for automatic cleanup
* @note datatype declared at discord-refcount.c
*/
struct _discord_ref *refs;
/** global lock */
pthread_mutex_t *g_lock;

struct anomap *maps[16];
pthread_mutex_t locks[16];
};

/**
Expand All @@ -970,10 +963,15 @@ void discord_refcounter_init(struct discord_refcounter *rc,
* no longer referenced
* @param should_free whether `data` cleanup should be followed by a free()
*/
void discord_refcounter_add_internal(struct discord_refcounter *rc,
void *data,
void (*cleanup)(void *data),
bool should_free);
#define discord_refcounter_add_internal(refcounter, data, cleanup, \
should_free) \
__discord_refcounter_add_internal(refcounter, __func__, data, cleanup, \
should_free)
void __discord_refcounter_add_internal(struct discord_refcounter *rc,
const char *name,
void *data,
void (*cleanup)(void *data),
bool should_free);

/**
* @brief Add a new client reference to the reference counter
Expand All @@ -984,11 +982,15 @@ void discord_refcounter_add_internal(struct discord_refcounter *rc,
* no longer referenced
* @param should_free whether `data` cleanup should be followed by a free()
*/
void discord_refcounter_add_client(struct discord_refcounter *rc,
void *data,
void (*cleanup)(struct discord *client,
void *data),
bool should_free);
#define discord_refcounter_add_client(refcounter, data, cleanup, should_free) \
__discord_refcounter_add_client(refcounter, __func__, data, cleanup, \
should_free)
void __discord_refcounter_add_client(struct discord_refcounter *rc,
const char *name,
void *data,
void (*cleanup)(struct discord *client,
void *data),
bool should_free);

/**
* @brief Cleanup refcounter and all user data currently held
Expand Down Expand Up @@ -1239,7 +1241,7 @@ struct discord {
pthread_mutex_t lock;
/** notify of `count` decrement */
pthread_cond_t cond;
} * workers;
} *workers;

#ifdef CCORD_VOICE
struct discord_voice *vcs;
Expand Down
Loading
Loading