* 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
*/
#include "lib/lfs.h"
#include "lib/asio.h"
#include "lib/conf.h"
-#include "lib/getopt.h"
+#include "lib/threads.h"
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
-#include <pthread.h>
static uns fbdir_cheat;
static uns fbdir_buffer_size = 65536;
#define FBDIR_ALIGN 512
-static pthread_key_t fbdir_queue_key;
-
enum fbdir_mode { // Current operating mode
M_NULL,
M_READ,
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
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);
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;
}
}
}
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;
}
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);
}
struct fastbuf *
-fbdirect_open_fd(int fd, struct asio_queue *q)
+fbdir_open_fd(int fd, struct asio_queue *q)
{
byte x[32];
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;
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));