diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h index 365a87596717660251a8bbd2bfbb73b4cca17a6a..23baa17b4ffdd9d1c51245399e99762871121cdb 100644 --- a/inc/lektor/cmd.h +++ b/inc/lektor/cmd.h @@ -26,4 +26,4 @@ noreturn void lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **arg in case of errors. */ extern const char *executable_name; -noreturn void help__(void); +noreturn void print_help(void); diff --git a/inc/lektor/thread.h b/inc/lektor/thread.h index d1fb59eb0214ad51948b931cba593c4e922c5641..56fe2cdf3b6951e20231c1cc37811cdbb73f5233 100644 --- a/inc/lektor/thread.h +++ b/inc/lektor/thread.h @@ -23,7 +23,6 @@ struct poller_thread_arg { void *args; }; - /* Create a new thread. Returns 0 on success, a non zero value on error. */ int poller_new(struct poller_thread *th, void *(*func)(struct poller_thread_arg *), void *args); diff --git a/inc/mthread/mthread.h b/inc/mthread/mthread.h index 869e0ddd4c3b0ecfc0b1e4eaca697a5a5761046a..6806967497f838685af43acaeb86b8f7fac5bfdd 100644 --- a/inc/mthread/mthread.h +++ b/inc/mthread/mthread.h @@ -36,8 +36,6 @@ typedef struct mthread_cond_s mthread_cond_t; struct mthread_condattr_s; typedef struct mthread_condattr_s mthread_condattr_t; -typedef unsigned int mthread_key_t; - typedef mthread_tst_t mthread_once_t; struct mthread_sem_s { @@ -54,53 +52,7 @@ extern mthread_t mthread_self(void); extern int mthread_equal (mthread_t __thread1, mthread_t __thread2); extern void mthread_exit (void *__retval); extern int mthread_join (mthread_t __th, void **__thread_return); - -/* Functions for mutex handling. */ - -extern int mthread_mutex_init (mthread_mutex_t *__mutex, const mthread_mutexattr_t *__mutex_attr); -extern int mthread_mutex_destroy(mthread_mutex_t *__mutex); -extern int mthread_mutex_trylock(mthread_mutex_t *__mutex); -extern int mthread_mutex_lock (mthread_mutex_t *__mutex); -extern int mthread_mutex_unlock (mthread_mutex_t *__mutex); - -/* Functions for handling conditional variables. */ - -extern int mthread_cond_init (mthread_cond_t *__cond, const mthread_condattr_t *__cond_attr); -extern int mthread_cond_destroy (mthread_cond_t *__cond); -extern int mthread_cond_signal (mthread_cond_t *__cond); -extern int mthread_cond_broadcast(mthread_cond_t *__cond); -extern int mthread_cond_wait (mthread_cond_t *__cond, mthread_mutex_t *__mutex); - -/* Functions for handling thread-specific data. */ - -extern int mthread_key_create (mthread_key_t *__key, void (*__destr_function) (void *)); -extern int mthread_key_delete (mthread_key_t __key); -extern int mthread_setspecific (mthread_key_t __key, const void *__pointer); -extern void *mthread_getspecific(mthread_key_t __key); - - -/* Functions for handling initialization. */ - -/* Guarantee that the initialization function INIT_ROUTINE will be called - only once, even if mthread_once is executed several times with the - same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or - variable initialized to MTHREAD_ONCE_INIT. - - The initialization functions might throw exception which is why - this function is not marked with . */ -extern int mthread_once(mthread_once_t *__once_control, void (*__init_routine) (void)); - -/* Functions for handling semaphore. */ - -extern int mthread_sem_init(mthread_sem_t *sem, unsigned int value); -extern int mthread_sem_wait(mthread_sem_t *sem); /* P(sem), wait(sem) */ -extern int mthread_sem_post(mthread_sem_t *sem); /* V(sem), signal(sem) */ - -extern int mthread_sem_getvalue(mthread_sem_t *sem, int *sval); -extern int mthread_sem_trywait (mthread_sem_t *sem); -extern int mthread_sem_destroy (mthread_sem_t *sem); /* undo sem_init() */ - -extern void mthread_yield(); +extern void mthread_yield (); /* Initialize mthread. */ diff --git a/inc/mthread/mthread_internal.h b/inc/mthread/mthread_internal.h index 285f337ed5d1ad1393382f36a9d2c4983a9cdcfb..832a019ddd28a08b7a88c22caf28402d04fd6e2b 100644 --- a/inc/mthread/mthread_internal.h +++ b/inc/mthread/mthread_internal.h @@ -31,14 +31,6 @@ typedef struct { typedef enum { RUNNING, BLOCKED, ZOMBIE } mthread_status_t; typedef volatile enum { JOINABLE = 0, DETACHED = 1, DETACHED_FREE = 2 } mthread_detached_flag_t; -#define INIT_KEYS_LIST 48 - -struct keys_list { - volatile mthread_key_t *list; - unsigned int first_avail; - unsigned int size; -}; - struct mthread_s { ucontext_t uc; volatile void *res; @@ -50,7 +42,6 @@ struct mthread_s { int not_migrable; mthread_virtual_processor_t *vp; void *stack; - struct keys_list keys; }; #define MTHREAD_LIST_INIT { .first = NULL, .last = NULL, .lock = 0 } diff --git a/meson.build b/meson.build index c73a83c2b77a585050199de16d311ac03bd6888f..480f732ba20fc552b9673890c0d80b4a51991040 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,6 @@ project( 'lektor' , version: '0.1.0' , license: 'ISC' , default_options: [ 'c_std=c18' - , 'cpp_std=c++17' , 'warning_level=3' , 'werror=true' , 'strip=true' @@ -38,16 +37,6 @@ endif ## Module list lektor_modules = [] -## Sources for mthread -mthread_sources = [ 'src/mthread/mthread.c' - , 'src/mthread/mthread_cond.c' - , 'src/mthread/mthread_key.c' - , 'src/mthread/mthread_mutex.c' - , 'src/mthread/mthread_once.c' - , 'src/mthread/mthread_sem.c' - , 'src/mthread/mthread_tst.c' - ] - ## Common files common_sources = [ 'src/common.c' , 'src/stack.c' @@ -59,7 +48,6 @@ common_sources = [ 'src/common.c' core_sources = [ 'src/mkv/write.c' , 'src/mkv/utils.c' , 'src/mkv/mkv.c' - , 'src/commands.c' , 'src/database/stickers.c' , 'src/database/open.c' , 'src/database/queue.c' @@ -72,6 +60,8 @@ core_sources = [ 'src/mkv/write.c' , 'src/net/listen.c' , 'src/net/message.c' , 'src/module/repo.c' + , 'src/mthread.c' + , 'src/commands.c' , 'src/config.c' , 'src/uri.c' , 'src/thread.c' @@ -110,7 +100,7 @@ xxd = generator( find_program('xxd') , arguments: [ '-i', '@INPUT@', '@OUTPUT@' ] ) lib = both_libraries( 'lektor' - , files(core_sources + mthread_sources) + , files(core_sources) , xxd.process('src/database/disk.sql') , xxd.process('src/database/memory.sql') , manpath diff --git a/meson_options.txt b/meson_options.txt index 9791739bdcb0f6034c5d537074d5d3adb1d3e768..5ac48a6a141ddd789bd84ff77a2308f8a5c7a862 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,3 @@ -option('static_modules', type: 'feature', value: 'enabled' - , description: 'Build modules and link them statically with lektord') -option('module_sdl', type: 'feature', value: 'enabled', description: 'Build the sdl module') -option('static_liblektor', type: 'boolean', value: true, description: 'Link the liblektor statically') +option('static_modules', type: 'feature', value: 'enabled', description: 'Build modules and link them statically with lektord') +option('module_sdl', type: 'feature', value: 'enabled', description: 'Build the sdl module') +option('static_liblektor', type: 'boolean', value: true, description: 'Link the liblektor statically') diff --git a/src/cmd.c b/src/cmd.c index 4f19b19519eafe19127bb3c2dc7245c35e0ebd85..3edfaa237d9960e7e84087ae476cc8e41c268bc3 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -13,7 +13,7 @@ const char *executable_name = NULL; extern const char *man_executable_path; noreturn void -help__(void) +print_help(void) { if (!executable_name) exit(EXIT_FAILURE); @@ -71,7 +71,7 @@ not_found: exit(EXIT_FAILURE); help: - help__(); + print_help(); not_exclusive: LOG_ERROR("COMMAND", "Failed to determine option, '%s' not exclusive", diff --git a/src/database/playlist.c b/src/database/playlist.c index a4b9b26c71516502a54e74277a9fd2ea12841cd2..d882ef0b125af1b09eafa29d6c65789d4bb68529 100644 --- a/src/database/playlist.c +++ b/src/database/playlist.c @@ -163,38 +163,15 @@ database_plt_add_uri(volatile sqlite3 *db, const char *name, struct lkt_uri *uri) { static const char *SQL = - "WITH plt_id(id) AS (SELECT playlist.id AS id FROM playlist" - " WHERE name COLLATE nocase = ?) " - "INSERT INTO kara_playlist (kara_id, playlist_id) " - "SELECT plt_id.id, kara.id " - " FROM kara, plt_id " - " WHERE kara.%s LIKE ? " - " ORDER BY RANDOM();"; + "INSERT OR REPLACE INTO kara_playlist (kara_id, playlist_id) " + "SELECT" + " kara.id," + " (SELECT playlist.id FROM playlist WHERE name = ? COLLATE NOCASE)" + "FROM kara WHERE kara.%s LIKE ?;"; char SQL_STMT[LKT_MAX_SQLITE_STATEMENT], sta = false; - const char *column; sqlite3_stmt *stmt; - switch (uri->type) { - case uri_type: - column = LKT_DB_TYPE; - break; - case uri_author: - column = LKT_DB_AUTHOR; - break; - case uri_category: - column = LKT_DB_CAT; - break; - case uri_language: - column = LKT_DB_LANG; - break; - case uri_query: - column = LKT_DB_ALL; - break; - default: - return false; - } - - safe_snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT, SQL, column); + safe_snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT, SQL, uri->column_name); SQLITE_PREPARE(db, stmt, SQL_STMT, error); SQLITE_BIND_TEXT(db, stmt, 1, name, error); SQLITE_BIND_TEXT(db, stmt, 2, (char *) uri->value, error); diff --git a/src/database/queue.c b/src/database/queue.c index 92d82e63b59c3e80a1a30828716d045993e21578..9762414cc190ac529b71ceaa860eea0cff1c9277 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -119,8 +119,10 @@ error: if (prio > 1) { \ if (__queue_reorder(db)) { \ LOG_INFO("DB", "%s", "Queue has been reordered"); \ - } else \ + } else { \ + LOG_INFO("DB", "%s", "Failed to reorder"); \ goto error; \ + } \ } static bool @@ -131,7 +133,7 @@ __queue_reorder(volatile sqlite3 *db) " ELSE (SELECT current FROM queue_state) END AS val LIMIT 1)" static const char *SQL_REORDER = /* Create temporary tables */ - "CREATE TEMPORARY TABLE queue_tmp" + "CREATE TEMPORARY TABLE queue_tmp IF NOT EXISTS" " ( position INTEGER PRIMARY KEY AUTOINCREMENT CHECK(position > 0)" " , kara_id INTEGER" " , priority INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)" @@ -146,7 +148,7 @@ __queue_reorder(volatile sqlite3 *db) " SELECT position + " CURRENT_POS_OR_0 ", kara_id, priority" " FROM queue_tmp;" /* Drop temporary tables */ - "DROP TABLE queue_tmp;" + "DELETE FROM queue_tmp;" "DELETE FROM sqlite_sequence WHERE name = 'queue_tmp';"; #undef CURRENT_POS_OR_0 SQLITE_EXEC(db, SQL_REORDER, error); @@ -274,7 +276,7 @@ database_queue_add_uri(volatile sqlite3 *db, struct lkt_uri *uri, int prio) case uri_author: return queue_add_with_col_like_str(db, LKT_DB_AUTHOR, uri->value, prio); case uri_playlist: - return database_queue_add_plt(db, (char *) uri->value, prio); + return database_queue_add_plt(db, uri->value, prio); default: LOG_WARN("DB", "Add to queue for uri of type %d is not" " implemented", uri->type); diff --git a/src/main/lkt.c b/src/main/lkt.c index f1f24c32e29c4770a3f5b38ef748536782f0ac57..ecf48701a9824fcfc2c2b9a4cfdaacb1b24217d9 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -733,7 +733,17 @@ plt_add__(struct lkt_cmd_args *args) FILE *sock = lkt_connect(); fail_if(args->argc < 3, "Invalid argument, need at least three arguments: plt add <plt> <query>"); fail_if(!lkt_valid_type(args->argv[1]), "Invalid argument, type for the query is invalid"); - send_cmd_with_uri(sock, "playlistadd", args->argc, args->argv); + + int i; + char buf[LKT_MESSAGE_MAX] = {0}; + for (i = 2; i < args->argc - 1; ++i) { + strncat(buf, args->argv[i], LKT_MESSAGE_MAX - 1); + strncat(buf, " ", LKT_MESSAGE_MAX - 1); + } + strncat(buf, args->argv[i], LKT_MESSAGE_MAX - 1); + strncat(buf, "\n", LKT_MESSAGE_MAX - 1); + write_socket(sock, "playlistadd %s %s://%s", args->argv[0], args->argv[1], buf); + exit_with_status(sock, buff); } diff --git a/src/main/server.c b/src/main/server.c index eb9054adff6f3dca159e2efb1fa555c3a1102274..0742684c853e1dc3f2a8e2d1c4efdf46e508f1ea 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -54,7 +54,7 @@ main(int argc, char *argv[]) break; case 'h': default: - help__(); + print_help(); exit(EXIT_SUCCESS); } } diff --git a/src/mthread/mthread.c b/src/mthread.c similarity index 85% rename from src/mthread/mthread.c rename to src/mthread.c index 3cd1d0ac2227e4deb4b93e90967dad36f471e787..48506d509401d38c1f9f90b258e4838aaba44f72 100644 --- a/src/mthread/mthread.c +++ b/src/mthread.c @@ -7,30 +7,83 @@ #define MTHREAD_LWP 1 -static mthread_virtual_processor_t virtual_processors[MTHREAD_MAX_VIRUTAL_PROCESSORS]; -static mthread_list_t joined_list; +#if defined(i686_ARCH) || defined(x86_64_ARCH) -/* Is mthread initialized */ -static volatile int is_mthread_init = 0; +static inline int +__mthread_test_and_set(mthread_tst_t *atomic) +{ + int ret; + __asm__ __volatile__("lock; xchgl %0, %1":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory"); + return ret; +} -static void -__mthread_clear_keys(mthread_t *thread) +#elif defined(sparc_ARCH) +static inline int +__mthread_test_and_set(mthread_tst_t *spinlock) { - RETURN_UNLESS(thread, "Invalid argument", NOTHING); - unsigned int i; - struct keys_list *keys = &(*thread)->keys; + char ret = 0; + __asm__ __volatile__("ldstub [%0], %1": "=r"(spinlock), "=r"(ret): "0"(spinlock), "1" (ret) : "memory"); + return (unsigned) ret; +} - if (!keys) { - keys->first_avail = 0; - return; - } +#elif defined(ia64_ARCH) +static __inline__ int +__mthread_test_and_set(mthread_tst_t *atomic) +{ + int ret; + __asm__ __volatile__("xchg4 %0=%1, %2":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory"); + return ret; +} +#else +#define USE_GENERIC_ASM +#include <pthread.h> +static pthread_mutex_t tst_mutex = PTHREAD_MUTEX_INITIALIZER; + +static inline int +__mthread_test_and_set(mthread_tst_t *atomic) +{ + int res; + pthread_mutex_lock(&tst_mutex); + res = *atomic; + if (*atomic == 0) + *atomic = 1; + pthread_mutex_unlock(&tst_mutex); + return res; +} +#endif - for (i = 0; i < keys->first_avail; ++i) - mthread_key_delete(keys->list[i]); +int +mthread_test_and_set(mthread_tst_t *atomic) +{ + return __mthread_test_and_set(atomic); +} - keys->first_avail = 0; +void +mthread_spinlock_lock(mthread_tst_t *atomic) +{ +#ifdef USE_GENERIC_ASM + static pthread_mutex_t spin_tst_mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&spin_tst_mutex); +#endif + while (mthread_test_and_set(atomic)) + sched_yield(); +#ifdef USE_GENERIC_ASM + pthread_mutex_unlock(&spin_tst_mutex); +#endif } +void +mthread_spinlock_unlock(mthread_tst_t *atomic) +{ + *atomic = 0; +} + +static mthread_virtual_processor_t virtual_processors[MTHREAD_MAX_VIRUTAL_PROCESSORS]; +static mthread_list_t joined_list; + +/* Is mthread initialized */ +static volatile int is_mthread_init = 0; + static inline void mthread_list_init(mthread_list_t *list) { @@ -370,7 +423,6 @@ mthread_join(mthread_t __th, void **__thread_return) if (__thread_return != NULL) *__thread_return = (void *)__th->res; - __mthread_clear_keys(&__th); LOG_INFO("THREAD END", "Thread %p joined", (void *) __th); mthread_insert_last(__th, &(joined_list)); return 0; diff --git a/src/mthread/mthread_cond.c b/src/mthread/mthread_cond.c deleted file mode 100644 index 1956f4420e5c3bbae4a10546c247369b9e9d3c01..0000000000000000000000000000000000000000 --- a/src/mthread/mthread_cond.c +++ /dev/null @@ -1,101 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include <mthread/mthread_internal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* Functions for handling conditional variables. */ - -/* Initialize condition variable COND using attributes ATTR, or use - the default values if later is NULL. */ -int -mthread_cond_init(mthread_cond_t *__cond, const mthread_condattr_t *__cond_attr) -{ - (void)__cond_attr; - __cond->lock = 0; - __cond->list = safe_malloc(sizeof(struct mthread_list_s)); - memset(__cond->list, 0, sizeof(struct mthread_list_s)); - LOG_INFO("MTHREAD", "%s", "Successfully created a condition"); - return 0; -} - -/* Destroy condition variable COND. */ -int -mthread_cond_destroy(mthread_cond_t *__cond) -{ - if (__cond->list) - free((void *) __cond->list); - return 0; -} - -/* Wake up one thread waiting for condition variable COND. */ -int -mthread_cond_signal(mthread_cond_t *__cond) -{ - mthread_t first, self = mthread_self(); - mthread_virtual_processor_t *vp; - int ret = 1; - mthread_spinlock_lock(&__cond->lock); - - if (__cond->list->first != NULL) { - first = mthread_remove_first(__cond->list); - vp = mthread_get_vp(); - first->status = RUNNING; - mthread_insert_last(first, &(vp->ready_list)); - LOG_INFO("MTHREAD", "Wake up the thread %p from the thread %p", - (void *) first, (void *) self); - ret = 0; - } else - LOG_INFO("MTHREAD", "No thread to wake up found from the thread %p", - (void *) self); - - mthread_spinlock_unlock(&__cond->lock); - return ret; -} - -/* Wake up all threads waiting for condition variables COND. */ -int -mthread_cond_broadcast(mthread_cond_t *__cond) -{ - mthread_t first, self = mthread_self(); - mthread_virtual_processor_t *vp; - mthread_spinlock_lock(&__cond->lock); - - while (__cond->list->first != NULL) { - first = mthread_remove_first(__cond->list); - vp = mthread_get_vp(); - first->status = RUNNING; - LOG_INFO("MTHREAD", "Wake up the thread %p from the thread %p", - (void *) first, (void *) self); - mthread_insert_last(first, &(vp->ready_list)); - } - - mthread_spinlock_unlock(&__cond->lock); - return 0; -} - -/* Wait for condition variable COND to be signaled or broadcast. - MUTEX is assumed to be locked before. */ -int -mthread_cond_wait(mthread_cond_t *__cond, mthread_mutex_t *__mutex) -{ - mthread_spinlock_lock(&__cond->lock); - mthread_t self = mthread_self(); - mthread_virtual_processor_t *vp = mthread_get_vp(); - mthread_insert_last(self, __cond->list); - self->status = BLOCKED; - mthread_mutex_unlock(__mutex); - - LOG_ERROR("MTHREAD", "Waiting in condition for thread %p", - (void *) self); - - vp->p = &__cond->lock; - mthread_yield(); - - mthread_mutex_lock(__mutex); - LOG_ERROR("MTHREAD", "Waike up in condition for thread %p", - (void *) self); - - return 0; -} diff --git a/src/mthread/mthread_key.c b/src/mthread/mthread_key.c deleted file mode 100644 index 96d650ddc7cb9eaf7b7923c894be5fbc84445a9d..0000000000000000000000000000000000000000 --- a/src/mthread/mthread_key.c +++ /dev/null @@ -1,165 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include <mthread/mthread_internal.h> -#include <errno.h> -#include <stdlib.h> - -/* TODO -> use binaty trees for better performance in searches. */ -typedef struct cell_s { - mthread_key_t key; - const volatile void *volatile spec; - void (* destr)(void *); - volatile struct cell_s *volatile next; -} cell_t; - -/* Default is 0. Index start at zero. Because of that the vairables hold the - first available slots and not the last used slots in memory. */ -static volatile mthread_key_t first_avail_key = 1; -static volatile cell_t *volatile key_table = NULL; - -/* Protects anything concerning the keys. */ -static mthread_tst_t lock = 0; - -/* Functions for handling thread-specific data. */ - -/* Create a key value identifying a location in the thread-specific - data area. Each thread maintains a distinct thread-specific data - area. DESTR_FUNCTION, if non-NULL, is called with the value - associated to that key when the key is destroyed. - DESTR_FUNCTION is not called if the value associated is NULL when - the key is destroyed. */ -int -mthread_key_create(mthread_key_t *__key, void (*__destr_function) (void *)) -{ - cell_t *new_cell = (cell_t *) safe_malloc(sizeof(cell_t)); - mthread_spinlock_lock(&lock); - - /* Creation. */ - new_cell->key = first_avail_key; - new_cell->spec = NULL; - new_cell->destr = __destr_function; - new_cell->next = NULL; - - first_avail_key++; - - if (key_table) { - new_cell->next = key_table; - key_table = new_cell; - } else - key_table = new_cell; - - /* Register key into the thread. */ - - struct keys_list *keys = &(mthread_self()->keys); - if (!keys->list) { - keys->list = (mthread_key_t *) safe_malloc(INIT_KEYS_LIST * sizeof(mthread_key_t)); - keys->first_avail = 0; - keys->size = INIT_KEYS_LIST; - } - - if (keys->size == keys->first_avail) { - /* Extend size if no space left. */ - void *new = realloc((void *) keys->list, (keys->size + INIT_KEYS_LIST) * sizeof(mthread_key_t)); - GOTO_UNLESS(new, "Could not increase the size of the key list", end); - keys->size += INIT_KEYS_LIST; - keys->list = new; - } - - /* Register the key into the thread. */ - keys->list[keys->first_avail] = new_cell->key; - keys->first_avail++; - - /* Returns. */ - *__key = new_cell->key; -end: - mthread_spinlock_unlock(&lock); - return errno; -} - -/* Destroy KEY. */ -int -mthread_key_delete(mthread_key_t __key) -{ - mthread_spinlock_lock(&lock); - - cell_t *it = (cell_t *) key_table; - cell_t *last = NULL; - - while (it != NULL && it->key != __key) { - last = it; - it = (cell_t *) it->next; - } - - if (!it) { - errno = EINVAL; - LOG_ERROR("MTHREAD", "Key %u not found", __key); - goto end; - } - - if (it->destr) { - LOG_INFO("MTHREAD", "Call function on data at %p", - (void *) it->spec); - it->destr((void *) it->spec); - } - - /* Handle deletion in the linked list. */ - - if (last) - last->next = it->next; - else - key_table = it->next; - - free(it); - LOG_INFO("MTHREAD", "Deleted key %u successfully", __key); - /* End of the function, simply returns. */ -end: - mthread_spinlock_unlock(&lock); - return errno; -} - -/* Store POINTER in the thread-specific data slot identified by KEY. */ -int -mthread_setspecific(mthread_key_t __key, const void *__pointer) -{ - mthread_spinlock_lock(&lock); - - cell_t *it = (cell_t *) key_table; - while (it != NULL && it->key != __key) - it = (cell_t *) it->next; - - if (!it) { - errno = EINVAL; - LOG_ERROR("MTHREAD", "Key %u not found", __key); - goto end; - } - - it->spec = __pointer; - /* End of the function, simply returns. */ -end: - mthread_spinlock_unlock(&lock); - return errno; -} - -/* Return current value of the thread-specific data slot identified by KEY. */ -void * -mthread_getspecific(mthread_key_t __key) -{ - void *ret = NULL; - mthread_spinlock_lock(&lock); - - cell_t *it = (cell_t *) key_table; - while (it != NULL && it->key != __key) - it = (cell_t *) it->next; - - if (!it) { - errno = EINVAL; - LOG_ERROR("MTHREAD", "Key %u not found", __key); - goto end; - } - - ret = (void *) it->spec; - /* End of the function, simply returns. */ -end: - mthread_spinlock_unlock(&lock); - return (void *) ret; -} diff --git a/src/mthread/mthread_mutex.c b/src/mthread/mthread_mutex.c deleted file mode 100644 index beb344bae6282d57d80d78c82aa8efbed26864f8..0000000000000000000000000000000000000000 --- a/src/mthread/mthread_mutex.c +++ /dev/null @@ -1,120 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include <common/common.h> -#include <errno.h> -#include <string.h> -#include <mthread/mthread_internal.h> - -/* Functions for mutex handling. */ - -/* Initialize MUTEX using attributes in *MUTEX_ATTR, or use the - default values if later is NULL. */ -int -mthread_mutex_init(mthread_mutex_t *__mutex, const mthread_mutexattr_t *__mutex_attr) -{ - UNUSED(__mutex_attr); - __mutex->list = safe_malloc(sizeof(mthread_list_t)); - __mutex->list->first = NULL; - __mutex->list->last = NULL; - __mutex->nb_thread = 0; - __mutex->lock = 0; - LOG_INFO("MTHREAD", "%s", "MUTEX initialized"); - return 0; -} - -/* Destroy MUTEX. */ -int -mthread_mutex_destroy(mthread_mutex_t *__mutex) -{ - mthread_spinlock_lock(&__mutex->lock); - - if (__mutex->nb_thread != 0) - return EBUSY; - free(__mutex->list); - __mutex->list = NULL; - - mthread_spinlock_unlock(&__mutex->lock); - return 0; -} - -/* Try to lock MUTEX. */ -int -mthread_mutex_trylock(mthread_mutex_t *__mutex) -{ - int retval = EINVAL; - - if (__mutex->list == NULL) { - __mutex->list = safe_malloc(sizeof(mthread_list_t)); - memset(__mutex->list, 0, sizeof(mthread_list_t)); - } - - mthread_spinlock_lock(&__mutex->lock); - - if (__mutex->nb_thread == 0) { - __mutex->nb_thread = 1; - mthread_spinlock_unlock(&__mutex->lock); - retval = 0; - goto end; - } - - mthread_spinlock_unlock(&__mutex->lock); - LOG_WARN("MTHREAD", "%s", "MUTEX busy"); - retval = EBUSY; - -end: - return retval; -} - -/* Wait until lock for MUTEX becomes available and lock it. */ -int -mthread_mutex_lock(mthread_mutex_t *__mutex) -{ - mthread_t self; - mthread_virtual_processor_t *vp; - - if (__mutex->list == NULL) { - __mutex->list = safe_malloc(sizeof(mthread_list_t)); - memset(__mutex->list, 0, sizeof(mthread_list_t)); - } - - mthread_spinlock_lock(&__mutex->lock); - - if (__mutex->nb_thread == 0) { - __mutex->nb_thread = 1; - mthread_spinlock_unlock(&__mutex->lock); - } else { - self = mthread_self(); - mthread_insert_last(self, __mutex->list); - self->status = BLOCKED; - vp = mthread_get_vp(); - vp->p = &__mutex->lock; - mthread_yield(); - } - - return 0; -} - -/* Unlock MUTEX. */ -int -mthread_mutex_unlock(mthread_mutex_t *__mutex) -{ - mthread_t first; - mthread_virtual_processor_t *vp; - - if (__mutex->list == NULL) { - __mutex->list = safe_malloc(sizeof(mthread_list_t)); - memset(__mutex->list, 0, sizeof(mthread_list_t)); - } - - mthread_spinlock_lock(&__mutex->lock); - if (__mutex->list->first != NULL) { - first = mthread_remove_first(__mutex->list); - vp = mthread_get_vp(); - first->status = RUNNING; - mthread_insert_last(first, &(vp->ready_list)); - } else - __mutex->nb_thread = 0; - - mthread_spinlock_unlock(&__mutex->lock); - return 0; -} diff --git a/src/mthread/mthread_once.c b/src/mthread/mthread_once.c deleted file mode 100644 index 9a269a39c13c61a7fac78fd713321ee9d8a17416..0000000000000000000000000000000000000000 --- a/src/mthread/mthread_once.c +++ /dev/null @@ -1,22 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include <mthread/mthread_internal.h> -#include <errno.h> - -/* Functions for handling initialization. */ - -/* Guarantee that the initialization function INIT_ROUTINE will be called - only once, even if mthread_once is executed several times with the - same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or - extern variable initialized to MTHREAD_ONCE_INIT. - - The initialization functions might throw exception which is why - this function is not marked with . */ -int -mthread_once (mthread_once_t *__once_control, void (*__init_routine) (void)) -{ - if (mthread_test_and_set(__once_control)) - return EAGAIN; - __init_routine(); - return 0; -} diff --git a/src/mthread/mthread_sem.c b/src/mthread/mthread_sem.c deleted file mode 100644 index 6d5acbcfc7b2ea4ce26c15b13e2fc33b364e21c8..0000000000000000000000000000000000000000 --- a/src/mthread/mthread_sem.c +++ /dev/null @@ -1,74 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include <mthread/mthread_internal.h> - -/* Functions for handling semaphore. */ - -int -mthread_sem_init(mthread_sem_t *sem, unsigned int value) -{ - sem->value = value; - mthread_mutex_init(&sem->mutex, NULL); - return 0; -} - -/* P(sem), wait(sem) */ -int -mthread_sem_wait(mthread_sem_t *sem) -{ - /* Here we loop while we can't enter the semaphore because there are already - the maximum number of clients. */ -loop: - mthread_mutex_lock(&sem->mutex); - if (sem->value == 0) { - mthread_mutex_unlock(&sem->mutex); - mthread_yield(); - goto loop; - } - - sem->value --; - mthread_mutex_unlock(&sem->mutex); - return 0; -} - -/* V(sem), signal(sem) */ -int -mthread_sem_post(mthread_sem_t *sem) -{ - mthread_mutex_lock(&sem->mutex); - sem->value ++; - mthread_mutex_unlock(&sem->mutex); - return 0; -} - -int -mthread_sem_getvalue(mthread_sem_t *sem, int *sval) -{ - *sval = sem->value; - return 0; -} - -int -mthread_sem_trywait(mthread_sem_t *sem) -{ - if (mthread_mutex_trylock(&sem->mutex)) - return 1; - - if (sem->value == 0) { - mthread_mutex_unlock(&sem->mutex); - return 1; - } - - sem->value --; - mthread_mutex_unlock(&sem->mutex); - return 0; -} - -/* undo sem_init() */ -int -mthread_sem_destroy(mthread_sem_t *sem) -{ - mthread_mutex_destroy(&sem->mutex); - sem->value = 0; - return 0; -} diff --git a/src/mthread/mthread_tst.c b/src/mthread/mthread_tst.c deleted file mode 100644 index 422eb485afe966b0e3aa996f797bdb03da6dcf9b..0000000000000000000000000000000000000000 --- a/src/mthread/mthread_tst.c +++ /dev/null @@ -1,75 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include <mthread/mthread_internal.h> -#include <sched.h> - -#if defined(i686_ARCH) || defined(x86_64_ARCH) - -static inline int -__mthread_test_and_set(mthread_tst_t *atomic) -{ - int ret; - __asm__ __volatile__("lock; xchgl %0, %1":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory"); - return ret; -} - -#elif defined(sparc_ARCH) -static inline int -__mthread_test_and_set(mthread_tst_t *spinlock) -{ - char ret = 0; - __asm__ __volatile__("ldstub [%0], %1": "=r"(spinlock), "=r"(ret): "0"(spinlock), "1" (ret) : "memory"); - return (unsigned) ret; -} - -#elif defined(ia64_ARCH) -static __inline__ int -__mthread_test_and_set(mthread_tst_t *atomic) -{ - int ret; - __asm__ __volatile__("xchg4 %0=%1, %2":"=r"(ret), "=m"(*atomic):"0"(1), "m"(*atomic):"memory"); - return ret; -} -#else -#define USE_GENERIC_ASM -#include <pthread.h> -static pthread_mutex_t tst_mutex = PTHREAD_MUTEX_INITIALIZER; - -static inline int -__mthread_test_and_set(mthread_tst_t *atomic) -{ - int res; - pthread_mutex_lock(&tst_mutex); - res = *atomic; - if (*atomic == 0) - *atomic = 1; - pthread_mutex_unlock(&tst_mutex); - return res; -} -#endif - -int -mthread_test_and_set(mthread_tst_t *atomic) -{ - return __mthread_test_and_set(atomic); -} - -void -mthread_spinlock_lock(mthread_tst_t *atomic) -{ -#ifdef USE_GENERIC_ASM - static pthread_mutex_t spin_tst_mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&spin_tst_mutex); -#endif - while (mthread_test_and_set(atomic)) - sched_yield(); -#ifdef USE_GENERIC_ASM - pthread_mutex_unlock(&spin_tst_mutex); -#endif -} - -void -mthread_spinlock_unlock(mthread_tst_t *atomic) -{ - *atomic = 0; -} diff --git a/src/uri.c b/src/uri.c index eaf64887a11c1a402e42baec6da808fee1191add..fd46447148178714dac4a0864d0adabcd8fd6c6a 100644 --- a/src/uri.c +++ b/src/uri.c @@ -29,7 +29,7 @@ __prefix(char *str, struct lkt_uri *ret) } else if (STR_NMATCH(str, "playlist", 8)) { ret->column_name = NULL; ret->type = uri_playlist; - val = str + 3; + val = str + 8; } else if (STR_NMATCH(str, "type", 4)) { ret->column_name = LKT_DB_TYPE; ret->type = uri_type;