1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source3/lib/asys/asys.h
Volker Lendecke c35fec883c asys: Allow multiple results to be received
This makes use of C99 dynamic arrays. In this performance-sensitive code, I
would like to avoid malloc/free, and I think 15 years after the standard we
might be able to use this feature. Alternatively, we could use the "results"
memory area and store the jobids in the upper range, playing some cast-tricks.
Should work as well.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2014-03-27 06:06:12 +01:00

155 lines
5.3 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
#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;
};
/**
* @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__ */