damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 3186b0e1d3872203517d2484401838f29a919e92
parent de0935582c25c17cb7926ad60139d5ce495178bc
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 12 Apr 2024 12:34:09 -0700

nostrdb: fix windows build

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mnostrdb/src/content_parser.c | 17+++++++++++++++++
Mnostrdb/src/nostr_bech32.c | 6++++--
Mnostrdb/src/nostrdb.c | 36++++++++++++++++++++++--------------
Mnostrdb/src/nostrdb.h | 4++++
Mnostrdb/src/print_util.h | 4++--
Mnostrdb/src/protected_queue.h | 5++++-
Anostrdb/src/thread.h | 43+++++++++++++++++++++++++++++++++++++++++++
Mnostrdb/src/threadpool.h | 6+++---
Mnostrdb/src/util.h | 8--------
Anostrdb/src/win.h | 9+++++++++
10 files changed, 108 insertions(+), 30 deletions(-)

diff --git a/nostrdb/src/content_parser.c b/nostrdb/src/content_parser.c @@ -3,8 +3,13 @@ #include "block.h" #include "nostrdb.h" #include "invoice.h" + +#ifndef _WIN32 #include "bolt11/bolt11.h" +#endif + #include "bolt11/bech32.h" + #include <stdlib.h> #include <string.h> @@ -164,6 +169,11 @@ fail: static int push_invoice_str(struct ndb_content_parser *p, struct ndb_str_block *str) { +#ifdef _WIN32 + // we shouldn't be pushing invoices on windows until we fix + // bolt11 parser portability + return 0; +#else unsigned char *start; struct bolt11 *bolt11; char *fail; @@ -186,6 +196,7 @@ static int push_invoice_str(struct ndb_content_parser *p, struct ndb_str_block * tal_free(bolt11); return 1; +#endif } int push_block(struct ndb_content_parser *p, struct ndb_block *block); @@ -455,6 +466,11 @@ static int parse_url(struct cursor *cur, struct ndb_block *block) { static int parse_invoice(struct cursor *cur, struct ndb_block *block) { unsigned char *start, *end; +#ifdef _WIN32 + // bolt11 stuff requires non-portable cc stuff, so ignore for now + return 0; +#else + // optional parse_str(cur, "lightning:"); @@ -478,6 +494,7 @@ static int parse_invoice(struct cursor *cur, struct ndb_block *block) { cur->p = end; return 1; +#endif } diff --git a/nostrdb/src/nostr_bech32.c b/nostrdb/src/nostr_bech32.c @@ -304,7 +304,7 @@ int parse_nostr_bech32(unsigned char *buf, int buflen, unsigned char *start; size_t parsed_len, u5_out_len, u8_out_len; enum nostr_bech32_type type; - static const int MAX_PREFIX = 8; +#define MAX_PREFIX 8 struct cursor cur, bech32, u8; make_cursor(buf, buf + buflen, &cur); @@ -320,7 +320,7 @@ int parse_nostr_bech32(unsigned char *buf, int buflen, if (parsed_len < 10 || parsed_len > 10000) return 0; - unsigned char u5[parsed_len]; + unsigned char *u5 = malloc(parsed_len); char prefix[MAX_PREFIX]; if (bech32_decode_len(prefix, u5, &u5_out_len, (const char*)start, @@ -332,6 +332,8 @@ int parse_nostr_bech32(unsigned char *buf, int buflen, if (!bech32_convert_bits(cur.p, &u8_out_len, 8, u5, u5_out_len, 5, 0)) return 0; + free(u5); + make_cursor(cur.p, cur.p + u8_out_len, &u8); return parse_nostr_bech32_buffer(&u8, type, obj); diff --git a/nostrdb/src/nostrdb.c b/nostrdb/src/nostrdb.c @@ -12,6 +12,7 @@ #include "cpu.h" #include "block.h" #include "threadpool.h" +#include "thread.h" #include "protected_queue.h" #include "memchr.h" #include "print_util.h" @@ -32,7 +33,7 @@ #define min(a,b) ((a) < (b) ? (a) : (b)) // the maximum number of things threads pop and push in bulk -static const int THREAD_QUEUE_BATCH = 4096; +#define THREAD_QUEUE_BATCH 4096 // maximum number of active subscriptions #define MAX_SUBSCRIPTIONS 256 @@ -84,7 +85,6 @@ struct ndb_tag { struct ndb_tags { uint16_t padding; uint16_t count; - struct ndb_tag tag[0]; }; // v1 @@ -364,8 +364,8 @@ static int ndb_tag_key_compare(const MDB_val *a, const MDB_val *b) if ((cmp = mdb_cmp_memn(&va, &vb))) return cmp; - ts_a = *(uint64_t*)(va.mv_data + va.mv_size); - ts_b = *(uint64_t*)(vb.mv_data + vb.mv_size); + ts_a = *(uint64_t*)((unsigned char *)va.mv_data + va.mv_size); + ts_b = *(uint64_t*)((unsigned char *)vb.mv_data + vb.mv_size); if (ts_a < ts_b) return -1; @@ -381,8 +381,8 @@ static int ndb_text_search_key_compare(const MDB_val *a, const MDB_val *b) uint64_t sa, sb, nid_a, nid_b; MDB_val a2, b2; - make_cursor(a->mv_data, a->mv_data + a->mv_size, &ca); - make_cursor(b->mv_data, b->mv_data + b->mv_size, &cb); + make_cursor(a->mv_data, (unsigned char *)a->mv_data + a->mv_size, &ca); + make_cursor(b->mv_data, (unsigned char *)b->mv_data + b->mv_size, &cb); // note_id if (unlikely(!cursor_pull_varint(&ca, &nid_a) || !cursor_pull_varint(&cb, &nid_b))) @@ -3035,7 +3035,7 @@ static int ndb_query_plan_execute_tags(struct ndb_txn *txn, if (taglen != k.mv_size - 9) break; - if (memcmp(k.mv_data+1, tag, k.mv_size-9)) + if (memcmp((unsigned char *)k.mv_data+1, tag, k.mv_size-9)) break; note_id = *(uint64_t*)v.mv_data; @@ -3538,7 +3538,7 @@ static int ndb_text_search_next_word(MDB_cursor *cursor, MDB_cursor_op op, int retries; retries = -1; - make_cursor(k->mv_data, k->mv_data + k->mv_size, &key_cursor); + make_cursor(k->mv_data, (unsigned char *)k->mv_data + k->mv_size, &key_cursor); // When op is MDB_SET_RANGE, this initializes the search. Position // the cursor at the next key greater than or equal to the specified @@ -3567,7 +3567,7 @@ retry: printf("\n"); */ - make_cursor(k->mv_data, k->mv_data + k->mv_size, &key_cursor); + make_cursor(k->mv_data, (unsigned char *)k->mv_data + k->mv_size, &key_cursor); if (unlikely(!ndb_unpack_text_search_key_noteid(&key_cursor, &result->key.note_id))) { fprintf(stderr, "UNUSUAL: failed to unpack text search key note_id\n"); @@ -4199,7 +4199,7 @@ static int ndb_writer_init(struct ndb_writer *writer, struct ndb_lmdb *lmdb, writer->queue_buflen, sizeof(struct ndb_writer_msg)); // spin up the writer thread - if (pthread_create(&writer->thread_id, NULL, ndb_writer_thread, writer)) + if (THREAD_CREATE(writer->thread_id, ndb_writer_thread, writer)) { fprintf(stderr, "ndb writer thread failed to create\n"); return 0; @@ -4244,9 +4244,9 @@ static int ndb_writer_destroy(struct ndb_writer *writer) msg.type = NDB_WRITER_QUIT; if (!prot_queue_push(&writer->inbox, &msg)) { // queue is too full to push quit message. just kill it. - pthread_exit(&writer->thread_id); + THREAD_TERMINATE(writer->thread_id); } else { - pthread_join(writer->thread_id, NULL); + THREAD_FINISH(writer->thread_id); } // cleanup @@ -4588,6 +4588,8 @@ int _ndb_process_events(struct ndb *ndb, const char *ldjson, size_t json_len, in return 1; } +#ifndef _WIN32 +// TODO: windows int ndb_process_events_stream(struct ndb *ndb, FILE* fp) { char *line = NULL; @@ -4605,6 +4607,7 @@ int ndb_process_events_stream(struct ndb *ndb, FILE* fp) return 1; } +#endif int ndb_process_client_events(struct ndb *ndb, const char *ldjson, size_t json_len) { @@ -6126,7 +6129,7 @@ int ndb_stat(struct ndb *ndb, struct ndb_stat *stat) /// Push an element to the current tag /// /// Basic idea is to call ndb_builder_new_tag -inline int ndb_builder_push_tag_str(struct ndb_builder *builder, +int ndb_builder_push_tag_str(struct ndb_builder *builder, const char *str, int len) { union ndb_packed_str pstr; @@ -6338,12 +6341,17 @@ void ndb_tags_iterate_start(struct ndb_note *note, struct ndb_iterator *iter) iter->index = -1; } +// Helper function to get a pointer to the nth tag +static struct ndb_tag *ndb_tags_tag(struct ndb_tags *tags, size_t index) { + return (struct ndb_tag *)((uint8_t *)tags + sizeof(struct ndb_tags) + index * sizeof(struct ndb_tag)); +} + int ndb_tags_iterate_next(struct ndb_iterator *iter) { struct ndb_tags *tags; if (iter->tag == NULL || iter->index == -1) { - iter->tag = iter->note->tags.tag; + iter->tag = ndb_tags_tag(&iter->note->tags, 0); iter->index = 0; return iter->note->tags.count != 0; } diff --git a/nostrdb/src/nostrdb.h b/nostrdb/src/nostrdb.h @@ -2,6 +2,7 @@ #define NOSTRDB_H #include <inttypes.h> +#include "win.h" #include "cursor.h" // maximum number of filters allowed in a filter group @@ -457,7 +458,10 @@ int ndb_init(struct ndb **ndb, const char *dbdir, const struct ndb_config *); int ndb_db_version(struct ndb *ndb); int ndb_process_event(struct ndb *, const char *json, int len); int ndb_process_events(struct ndb *, const char *ldjson, size_t len); +#ifndef _WIN32 +// TODO: fix on windows int ndb_process_events_stream(struct ndb *, FILE* fp); +#endif int ndb_process_client_event(struct ndb *, const char *json, int len); int ndb_process_client_events(struct ndb *, const char *json, size_t len); int ndb_begin_query(struct ndb *, struct ndb_txn *); diff --git a/nostrdb/src/print_util.h b/nostrdb/src/print_util.h @@ -22,12 +22,12 @@ static void print_tag_kv(struct ndb_txn *txn, MDB_val *k, MDB_val *v) struct ndb_note *note; uint64_t ts; - ts = *(uint64_t*)(k->mv_data+(k->mv_size-8)); + ts = *(uint64_t*)((uint8_t*)k->mv_data+(k->mv_size-8)); // TODO: p tags, etc if (((const char*)k->mv_data)[0] == 'e' && k->mv_size == (1 + 32 + 8)) { printf("note_tags 'e"); - print_hex(k->mv_data+1, 32); + print_hex((uint8_t*)k->mv_data+1, 32); printf("' %" PRIu64, ts); } else { printf("note_tags '%.*s' %" PRIu64, (int)k->mv_size-8, diff --git a/nostrdb/src/protected_queue.h b/nostrdb/src/protected_queue.h @@ -12,12 +12,15 @@ #ifndef PROT_QUEUE_H #define PROT_QUEUE_H -#include <pthread.h> #include <stdbool.h> #include <stddef.h> #include <string.h> #include "cursor.h" #include "util.h" +#include "thread.h" + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) /* * The prot_queue structure represents a thread-safe queue that can hold diff --git a/nostrdb/src/thread.h b/nostrdb/src/thread.h @@ -0,0 +1,43 @@ +#ifndef NDB_THREAD_H +#define NDB_THREAD_H + +#ifdef _WIN32 + #include <windows.h> + + #define ErrCode() GetLastError() + #define pthread_t HANDLE + #define pthread_mutex_t HANDLE + #define pthread_cond_t HANDLE + #define pthread_cond_destroy(x) + #define pthread_mutex_unlock(x) ReleaseMutex(*x) + #define pthread_mutex_destroy(x) \ + (CloseHandle(*x) ? 0 : ErrCode()) + #define pthread_mutex_lock(x) WaitForSingleObject(*x, INFINITE) + #define pthread_mutex_init(mutex, attr) \ + ((*mutex = CreateMutex(NULL, FALSE, NULL)) ? 0 : ErrCode()) + #define pthread_cond_init(x, attr) (InitializeConditionVariable(x), 0) + #define pthread_cond_signal(x) SetEvent(*x) + #define pthread_cond_wait(cond,mutex) do{SignalObjectAndWait(*mutex, *cond, INFINITE, FALSE); WaitForSingleObject(*mutex, INFINITE);}while(0) + #define THREAD_CREATE(thr,start,arg) \ + (((thr) = CreateThread(NULL, 0, start, arg, 0, NULL)) ? 0 : ErrCode()) + #define THREAD_FINISH(thr) \ + (WaitForSingleObject(thr, INFINITE) ? ErrCode() : 0) + #define THREAD_TERMINATE(thr) \ + (TerminateThread(thr, 0) ? ErrCode() : 0) + #define LOCK_MUTEX(mutex) WaitForSingleObject(mutex, INFINITE) + #define UNLOCK_MUTEX(mutex) ReleaseMutex(mutex) + +#else // _WIN32 + #include <pthread.h> + + //#define ErrCode() errno + #define THREAD_CREATE(thr,start,arg) pthread_create(&thr,NULL,start,arg) + #define THREAD_FINISH(thr) pthread_join(thr,NULL) + #define THREAD_TERMINATE(thr) pthread_exit(&thr) + + #define LOCK_MUTEX(mutex) pthread_mutex_lock(mutex) + #define UNLOCK_MUTEX(mutex) pthread_mutex_unlock(mutex) + +#endif + +#endif // NDB_THREAD_H diff --git a/nostrdb/src/threadpool.h b/nostrdb/src/threadpool.h @@ -55,7 +55,7 @@ static int threadpool_init(struct threadpool *tp, int num_threads, return 0; } - if (pthread_create(&t->thread_id, NULL, thread_fn, t) != 0) { + if (THREAD_CREATE(t->thread_id, thread_fn, t) != 0) { fprintf(stderr, "threadpool_init: failed to create thread\n"); return 0; } @@ -90,9 +90,9 @@ static inline void threadpool_destroy(struct threadpool *tp) for (int i = 0; i < tp->num_threads; i++) { t = &tp->pool[i]; if (!prot_queue_push(&t->inbox, tp->quit_msg)) { - pthread_exit(&t->thread_id); + THREAD_TERMINATE(t->thread_id); } else { - pthread_join(t->thread_id, NULL); + THREAD_FINISH(t->thread_id); } prot_queue_destroy(&t->inbox); free(t->qmem); diff --git a/nostrdb/src/util.h b/nostrdb/src/util.h @@ -2,14 +2,6 @@ #ifndef NDB_UTIL_H #define NDB_UTIL_H -static inline int min(int a, int b) { - return a < b ? a : b; -} - -static inline int max(int a, int b) { - return a > b ? a : b; -} - static inline void* memdup(const void* src, size_t size) { void* dest = malloc(size); if (dest == NULL) { diff --git a/nostrdb/src/win.h b/nostrdb/src/win.h @@ -0,0 +1,9 @@ +#ifndef NOSTRDB_WIN_H +#define NOSTRDB_WIN_H +#ifdef _WIN32 + +typedef ptrdiff_t ssize_t; // ssize_t is typically a signed version of size_t + +#endif +#endif // NOSTRDB_WIN_H +