#include "syscall.h"
#include "atomic.h"
#include "pthread_impl.h"
+#include "aio_impl.h"
+
+#define malloc __libc_malloc
+#define calloc __libc_calloc
+#define realloc __libc_realloc
+#define free __libc_free
/* The following is a threads-based implementation of AIO with minimal
* dependence on implementation details. Most synchronization is
static volatile int aio_fd_cnt;
volatile int __aio_fut;
+static size_t io_thread_stack_size;
+
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+
static struct aio_queue *__aio_get_queue(int fd, int need)
{
if (fd < 0) {
pthread_rwlock_unlock(&maplock);
if (fcntl(fd, F_GETFD) < 0) return 0;
pthread_rwlock_wrlock(&maplock);
+ if (!io_thread_stack_size) {
+ unsigned long val = __getauxval(AT_MINSIGSTKSZ);
+ io_thread_stack_size = MAX(MINSIGSTKSZ+2048, val+512);
+ }
if (!map) map = calloc(sizeof *map, (-1U/2+1)>>24);
if (!map) goto out;
if (!map[a]) map[a] = calloc(sizeof **map, 256);
return 0;
}
-static size_t io_thread_stack_size = MINSIGSTKSZ+2048;
-static pthread_once_t init_stack_size_once;
-
-static void init_stack_size()
-{
- unsigned long val = __getauxval(AT_MINSIGSTKSZ);
- if (val > MINSIGSTKSZ) io_thread_stack_size = val + 512;
-}
-
static int submit(struct aiocb *cb, int op)
{
int ret = 0;
if (!q) {
if (errno != EBADF) errno = EAGAIN;
+ cb->__ret = -1;
+ cb->__err = errno;
return -1;
}
q->ref++;
else
pthread_attr_init(&a);
} else {
- pthread_once(&init_stack_size_once, init_stack_size);
pthread_attr_init(&a);
pthread_attr_setstacksize(&a, io_thread_stack_size);
pthread_attr_setguardsize(&a, 0);
if (pthread_create(&td, &a, io_thread_func, &args)) {
pthread_mutex_lock(&q->lock);
__aio_unref_queue(q);
- errno = EAGAIN;
- ret = -1;
+ cb->__err = errno = EAGAIN;
+ cb->__ret = ret = -1;
}
pthread_sigmask(SIG_SETMASK, &origmask, 0);
return fd;
}
+void __aio_atfork(int who)
+{
+ if (who<0) {
+ pthread_rwlock_rdlock(&maplock);
+ return;
+ }
+ if (who>0 && map) for (int a=0; a<(-1U/2+1)>>24; a++)
+ if (map[a]) for (int b=0; b<256; b++)
+ if (map[a][b]) for (int c=0; c<256; c++)
+ if (map[a][b][c]) for (int d=0; d<256; d++)
+ map[a][b][c][d] = 0;
+ pthread_rwlock_unlock(&maplock);
+}
+
weak_alias(aio_cancel, aio_cancel64);
weak_alias(aio_error, aio_error64);
weak_alias(aio_fsync, aio_fsync64);