diff --git a/source3/lib/asys/asys.c b/source3/lib/asys/asys.c deleted file mode 100644 index 594d47004ba..00000000000 --- a/source3/lib/asys/asys.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Async syscalls - * Copyright (C) Volker Lendecke 2012 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "asys.h" -#include -#include -#include "../pthreadpool/pthreadpool_pipe.h" -#include "lib/util/time.h" -#include "smbprofile.h" - -struct asys_pwrite_args { - int fildes; - const void *buf; - size_t nbyte; - off_t offset; -}; - -struct asys_pread_args { - int fildes; - void *buf; - size_t nbyte; - off_t offset; -}; - -struct asys_fsync_args { - int fildes; -}; - -union asys_job_args { - struct asys_pwrite_args pwrite_args; - struct asys_pread_args pread_args; - struct asys_fsync_args fsync_args; -}; - -struct asys_job { - void *private_data; - union asys_job_args args; - ssize_t ret; - int err; - char busy; - char canceled; - struct timespec start_time; - struct timespec end_time; -}; - -struct asys_context { - struct pthreadpool_pipe *pool; - int pthreadpool_pipe_fd; - - unsigned num_jobs; - struct asys_job **jobs; -}; - -struct asys_creds_context { - int dummy; -}; - -int asys_context_init(struct asys_context **pctx, unsigned max_parallel) -{ - struct asys_context *ctx; - int ret; - - ctx = calloc(1, sizeof(struct asys_context)); - if (ctx == NULL) { - return ENOMEM; - } - ret = pthreadpool_pipe_init(max_parallel, &ctx->pool); - if (ret != 0) { - free(ctx); - return ret; - } - ctx->pthreadpool_pipe_fd = pthreadpool_pipe_signal_fd(ctx->pool); - - *pctx = ctx; - return 0; -} - -int asys_signalfd(struct asys_context *ctx) -{ - return ctx->pthreadpool_pipe_fd; -} - -int asys_context_destroy(struct asys_context *ctx) -{ - int ret; - unsigned i; - - for (i=0; inum_jobs; i++) { - if (ctx->jobs[i]->busy) { - return EBUSY; - } - } - - ret = pthreadpool_pipe_destroy(ctx->pool); - if (ret != 0) { - return ret; - } - for (i=0; inum_jobs; i++) { - free(ctx->jobs[i]); - } - free(ctx->jobs); - free(ctx); - return 0; -} - -static int asys_new_job(struct asys_context *ctx, int *jobid, - struct asys_job **pjob) -{ - struct asys_job **tmp; - struct asys_job *job; - unsigned i; - - for (i=0; inum_jobs; i++) { - job = ctx->jobs[i]; - if (!job->busy) { - job->err = 0; - *pjob = job; - *jobid = i; - return 0; - } - } - - if (ctx->num_jobs+1 == 0) { - return EBUSY; /* overflow */ - } - - tmp = realloc(ctx->jobs, sizeof(struct asys_job *)*(ctx->num_jobs+1)); - if (tmp == NULL) { - return ENOMEM; - } - ctx->jobs = tmp; - - job = calloc(1, sizeof(struct asys_job)); - if (job == NULL) { - return ENOMEM; - } - ctx->jobs[ctx->num_jobs] = job; - - *jobid = ctx->num_jobs; - *pjob = job; - ctx->num_jobs += 1; - return 0; -} - -static void asys_pwrite_do(void *private_data); - -int asys_pwrite(struct asys_context *ctx, int fildes, const void *buf, - size_t nbyte, off_t offset, void *private_data) -{ - struct asys_job *job; - struct asys_pwrite_args *args; - int jobid; - int ret; - - ret = asys_new_job(ctx, &jobid, &job); - if (ret != 0) { - return ret; - } - job->private_data = private_data; - - args = &job->args.pwrite_args; - args->fildes = fildes; - args->buf = buf; - args->nbyte = nbyte; - args->offset = offset; - - ret = pthreadpool_pipe_add_job(ctx->pool, jobid, asys_pwrite_do, job); - if (ret != 0) { - return ret; - } - job->busy = 1; - - return 0; -} - -static void asys_pwrite_do(void *private_data) -{ - struct asys_job *job = (struct asys_job *)private_data; - struct asys_pwrite_args *args = &job->args.pwrite_args; - - PROFILE_TIMESTAMP(&job->start_time); - job->ret = pwrite(args->fildes, args->buf, args->nbyte, args->offset); - PROFILE_TIMESTAMP(&job->end_time); - - if (job->ret == -1) { - job->err = errno; - } -} - -static void asys_pread_do(void *private_data); - -int asys_pread(struct asys_context *ctx, int fildes, void *buf, - size_t nbyte, off_t offset, void *private_data) -{ - struct asys_job *job; - struct asys_pread_args *args; - int jobid; - int ret; - - ret = asys_new_job(ctx, &jobid, &job); - if (ret != 0) { - return ret; - } - job->private_data = private_data; - - args = &job->args.pread_args; - args->fildes = fildes; - args->buf = buf; - args->nbyte = nbyte; - args->offset = offset; - - ret = pthreadpool_pipe_add_job(ctx->pool, jobid, asys_pread_do, job); - if (ret != 0) { - return ret; - } - job->busy = 1; - - return 0; -} - -static void asys_pread_do(void *private_data) -{ - struct asys_job *job = (struct asys_job *)private_data; - struct asys_pread_args *args = &job->args.pread_args; - - PROFILE_TIMESTAMP(&job->start_time); - job->ret = pread(args->fildes, args->buf, args->nbyte, args->offset); - PROFILE_TIMESTAMP(&job->end_time); - - if (job->ret == -1) { - job->err = errno; - } -} - -static void asys_fsync_do(void *private_data); - -int asys_fsync(struct asys_context *ctx, int fildes, void *private_data) -{ - struct asys_job *job; - struct asys_fsync_args *args; - int jobid; - int ret; - - ret = asys_new_job(ctx, &jobid, &job); - if (ret != 0) { - return ret; - } - job->private_data = private_data; - - args = &job->args.fsync_args; - args->fildes = fildes; - - ret = pthreadpool_pipe_add_job(ctx->pool, jobid, asys_fsync_do, job); - if (ret != 0) { - return ret; - } - job->busy = 1; - - return 0; -} - -static void asys_fsync_do(void *private_data) -{ - struct asys_job *job = (struct asys_job *)private_data; - struct asys_fsync_args *args = &job->args.fsync_args; - - PROFILE_TIMESTAMP(&job->start_time); - job->ret = fsync(args->fildes); - PROFILE_TIMESTAMP(&job->end_time); - - if (job->ret == -1) { - job->err = errno; - } -} - -void asys_cancel(struct asys_context *ctx, void *private_data) -{ - unsigned i; - - for (i=0; inum_jobs; i++) { - struct asys_job *job = ctx->jobs[i]; - - if (job->private_data == private_data) { - job->canceled = 1; - } - } -} - -int asys_results(struct asys_context *ctx, struct asys_result *results, - unsigned num_results) -{ - int jobids[num_results]; - int i, ret; - - ret = pthreadpool_pipe_finished_jobs(ctx->pool, jobids, num_results); - if (ret <= 0) { - return ret; - } - - for (i=0; i= ctx->num_jobs)) { - return -EIO; - } - - job = ctx->jobs[jobid]; - - if (job->canceled) { - result->ret = -1; - result->err = ECANCELED; - } else { - result->ret = job->ret; - result->err = job->err; - } - result->private_data = job->private_data; - result->duration = nsec_time_diff(&job->end_time, &job->start_time); - - job->busy = 0; - } - - return ret; -} diff --git a/source3/lib/asys/asys.h b/source3/lib/asys/asys.h deleted file mode 100644 index f576bd32781..00000000000 --- a/source3/lib/asys/asys.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Async syscalls - * Copyright (C) Volker Lendecke 2012 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __ASYS_H__ -#define __ASYS_H__ - -#include "replace.h" -#include "system/filesys.h" - -/** - * @defgroup asys The async syscall library - * - * This module contains a set of asynchronous functions that directly - * wrap normally synchronous posix system calls. The reason for this - * module's existence is the limited set of operations the posix async - * I/O API provides. - * - * The basic flow of operations is: - * - * The application creates a asys_context structure using - * asys_context_create() - * - * The application triggers a call to the library by calling for - * example asys_ftruncate(). asys_ftruncate() takes a private_data - * argument that will be returned later by asys_result. The calling - * application should hand a pointer representing the async operation - * to the private_data argument. - * - * The application puts the fd returned by asys_signalfd() into its - * event loop. When the signal fd becomes readable, the application - * calls asys_result() to grab the final result of one of the system - * calls that were issued in the meantime. - * - * For multi-user applications it is necessary to create different - * credential contexts, as it is not clear when exactly the real - * system call will be issued. The application might have called - * seteuid(2) or something equivalent in the meantime. Thus, all - * system calls doing access checks, in particular all calls doing - * path-based operations, require a struct auth_creds_context - * parameter. asys_creds_context_create() creates such a context. All - * credential-checking operations take a struct asys_creds_context as - * an argument. It can be NULL if the application never changes - * credentials. - * - * @{ - */ - -struct asys_context; -struct asys_creds_context; - -enum asys_log_level { - ASYS_LOG_FATAL = 0, - ASYS_DEBUG_ERROR, - ASYS_DEBUG_WARNING, - ASYS_DEBUG_TRACE -}; - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -typedef void (*asys_log_fn)(struct asys_context *ctx, void *private_data, - enum asys_log_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(4, 5); - -int asys_context_init(struct asys_context **ctx, unsigned max_parallel); -int asys_context_destroy(struct asys_context *ctx); -void asys_set_log_fn(struct asys_context *ctx, asys_log_fn fn, - void *private_data); - -/** - * @brief Get the the signal fd - * - * asys_signalfd() returns a file descriptor that will become readable - * whenever an asynchronous request has finished. When the signalfd is - * readable, calling asys_result() will not block. - * - * @param[in] ctx The asys context - * @return A file descriptor indicating a finished operation - */ - -int asys_signalfd(struct asys_context *ctx); - -struct asys_result { - ssize_t ret; - int err; - void *private_data; - uint64_t duration; /* nanoseconds */ -}; - -/** - * @brief Pull the results from async operations - * - * Whe the fd returned from asys_signalfd() is readable, one or more async - * operations have finished. The result from the async operations can be pulled - * with asys_results(). - * - * @param[in] ctx The asys context - * @param[out] results The result strutcts - * @param[in] num_results The length of the results array - * @return success: >=0, number of finished jobs - * failure: -errno - */ -int asys_results(struct asys_context *ctx, struct asys_result *results, - unsigned num_results); - -void asys_cancel(struct asys_context *ctx, void *private_data); - -int asys_pread(struct asys_context *ctx, int fildes, void *buf, size_t nbyte, - off_t offset, void *private_data); -int asys_pwrite(struct asys_context *ctx, int fildes, const void *buf, - size_t nbyte, off_t offset, void *private_data); -int asys_ftruncate(struct asys_context *ctx, int filedes, off_t length, - void *private_data); -int asys_fsync(struct asys_context *ctx, int fd, void *private_data); -int asys_close(struct asys_context *ctx, int fd, void *private_data); - -struct asys_creds_context *asys_creds_context_create( - struct asys_context *ctx, - uid_t uid, gid_t gid, unsigned num_gids, gid_t *gids); - -int asys_creds_context_delete(struct asys_creds_context *ctx); - -int asys_open(struct asys_context *ctx, struct asys_creds_context *cctx, - const char *pathname, int flags, mode_t mode, - void *private_data); -int asys_unlink(struct asys_context *ctx, struct asys_creds_context *cctx, - const char *pathname, void *private_data); - -/* @} */ - -#endif /* __ASYS_H__ */ diff --git a/source3/lib/asys/tests.c b/source3/lib/asys/tests.c deleted file mode 100644 index e54e3ea2d22..00000000000 --- a/source3/lib/asys/tests.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Test async syscalls - * Copyright (C) Volker Lendecke 2012 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "asys.h" -#include -#include -#include -#include - -int main(int argc, const char *argv[]) -{ - struct asys_context *ctx; - int i, fd, ret; - - int *buf; - - int ntasks = 10; - - ret = asys_context_init(&ctx, 0); - if (ret != 0) { - perror("asys_context_create failed"); - return 1; - } - - fd = open("asys_testfile", O_CREAT|O_RDWR, 0644); - if (fd == -1) { - perror("open failed"); - return 1; - } - - buf = calloc(ntasks, sizeof(int)); - if (buf == NULL) { - perror("calloc failed"); - return 1; - } - - for (i=0; i