X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Ffb-direct.c;h=c3b74e1592edf698ce593e4cca6745afddee6c78;hb=8d69e71b6fd71828c7aa3f89650650e92d08d305;hp=e6254752a3de63d3155e14632055baa1712fe3bd;hpb=7b9f085a0cc79ca3263b1fdaff66119bd03a49f6;p=libucw.git diff --git a/lib/fb-direct.c b/lib/fb-direct.c index e6254752..c3b74e15 100644 --- a/lib/fb-direct.c +++ b/lib/fb-direct.c @@ -19,7 +19,6 @@ * and take care of locking. * * FIXME: what if the OS doesn't support O_DIRECT? - * FIXME: doc: don't mix threads * FIXME: unaligned seeks and partial writes? * FIXME: merge with other file-oriented fastbufs */ @@ -31,12 +30,11 @@ #include "lib/lfs.h" #include "lib/asio.h" #include "lib/conf.h" -#include "lib/getopt.h" +#include "lib/threads.h" #include #include #include -#include static uns fbdir_cheat; static uns fbdir_buffer_size = 65536; @@ -55,8 +53,6 @@ static struct cf_section fbdir_cf = { #define FBDIR_ALIGN 512 -static pthread_key_t fbdir_queue_key; - enum fbdir_mode { // Current operating mode M_NULL, M_READ, @@ -81,8 +77,6 @@ static void CONSTRUCTOR fbdir_global_init(void) { cf_declare_section("FBDirect", &fbdir_cf, 0); - if (pthread_key_create(&fbdir_queue_key, NULL) < 0) - die("Cannot create fbdir_queue_key: %m"); } static void @@ -233,14 +227,15 @@ fbdir_seek(struct fastbuf *f, sh_off_t pos, int whence) static struct asio_queue * fbdir_get_io_queue(void) { - struct asio_queue *q = pthread_getspecific(fbdir_queue_key); + struct ucwlib_context *ctx = ucwlib_thread_context(); + struct asio_queue *q = ctx->io_queue; if (!q) { q = xmalloc_zero(sizeof(struct asio_queue)); q->buffer_size = fbdir_buffer_size; q->max_writebacks = fbdir_write_back; asio_init_queue(q); - pthread_setspecific(fbdir_queue_key, q); + ctx->io_queue = q; } q->use_count++; DBG("FB-DIRECT: Got I/O queue, uc=%d", q->use_count); @@ -250,14 +245,15 @@ fbdir_get_io_queue(void) static void fbdir_put_io_queue(void) { - struct asio_queue *q = pthread_getspecific(fbdir_queue_key); + struct ucwlib_context *ctx = ucwlib_thread_context(); + struct asio_queue *q = ctx->io_queue; ASSERT(q); DBG("FB-DIRECT: Put I/O queue, uc=%d", q->use_count); if (!--q->use_count) { asio_cleanup_queue(q); xfree(q); - pthread_setspecific(fbdir_queue_key, NULL); + ctx->io_queue = NULL; } } @@ -323,7 +319,7 @@ fbdir_open_internal(byte *name, int fd, struct asio_queue *q) } struct fastbuf * -fbdirect_open_try(byte *name, uns mode, struct asio_queue *q) +fbdir_open_try(byte *name, uns mode, struct asio_queue *q) { if (!fbdir_cheat) mode |= O_DIRECT; @@ -337,9 +333,9 @@ fbdirect_open_try(byte *name, uns mode, struct asio_queue *q) } struct fastbuf * -fbdirect_open(byte *name, uns mode, struct asio_queue *q) +fbdir_open(byte *name, uns mode, struct asio_queue *q) { - struct fastbuf *b = fbdirect_open_try(name, mode, q); + struct fastbuf *b = fbdir_open_try(name, mode, q); if (!b) die("Unable to %s file %s: %m", (mode & O_CREAT) ? "create" : "open", name); @@ -347,7 +343,7 @@ fbdirect_open(byte *name, uns mode, struct asio_queue *q) } struct fastbuf * -fbdirect_open_fd(int fd, struct asio_queue *q) +fbdir_open_fd(int fd, struct asio_queue *q) { byte x[32]; @@ -357,8 +353,22 @@ fbdirect_open_fd(int fd, struct asio_queue *q) return fbdir_open_internal(x, fd, q); } +struct fastbuf * +fbdir_open_tmp(struct asio_queue *q) +{ + byte buf[TEMP_FILE_NAME_LEN]; + struct fastbuf *f; + + temp_file_name(buf); + f = fbdir_open(buf, O_RDWR | O_CREAT | O_TRUNC, q); + bconfig(f, BCONFIG_IS_TEMP_FILE, 1); + return f; +} + #ifdef TEST +#include "lib/getopt.h" + int main(int argc, char **argv) { struct fastbuf *f, *t; @@ -366,8 +376,8 @@ int main(int argc, char **argv) log_init(NULL); if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0) die("Hey, whaddya want?"); - f = (optind < argc) ? fbdirect_open(argv[optind++], O_RDONLY, NULL) : fbdirect_open_fd(0, NULL); - t = (optind < argc) ? fbdirect_open(argv[optind++], O_RDWR | O_CREAT | O_TRUNC, NULL) : fbdirect_open_fd(1, NULL); + f = (optind < argc) ? fbdir_open(argv[optind++], O_RDONLY, NULL) : fbdir_open_fd(0, NULL); + t = (optind < argc) ? fbdir_open(argv[optind++], O_RDWR | O_CREAT | O_TRUNC, NULL) : fbdir_open_fd(1, NULL); bbcopy(f, t, ~0U); ASSERT(btell(f) == btell(t));