Commit 8653c0158c23ec592f0041ab48b83d6cc6d152fe
1 parent
5518f3a6
Error checking
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6630 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
72 additions
and
24 deletions
posix-aio-compat.c
| @@ -15,6 +15,9 @@ | @@ -15,6 +15,9 @@ | ||
| 15 | #include <unistd.h> | 15 | #include <unistd.h> |
| 16 | #include <errno.h> | 16 | #include <errno.h> |
| 17 | #include <sys/time.h> | 17 | #include <sys/time.h> |
| 18 | +#include <string.h> | ||
| 19 | +#include <stdlib.h> | ||
| 20 | +#include <stdio.h> | ||
| 18 | #include "osdep.h" | 21 | #include "osdep.h" |
| 19 | 22 | ||
| 20 | #include "posix-aio-compat.h" | 23 | #include "posix-aio-compat.h" |
| @@ -27,20 +30,64 @@ static int cur_threads = 0; | @@ -27,20 +30,64 @@ static int cur_threads = 0; | ||
| 27 | static int idle_threads = 0; | 30 | static int idle_threads = 0; |
| 28 | static TAILQ_HEAD(, qemu_paiocb) request_list; | 31 | static TAILQ_HEAD(, qemu_paiocb) request_list; |
| 29 | 32 | ||
| 33 | +static void die2(int err, const char *what) | ||
| 34 | +{ | ||
| 35 | + fprintf(stderr, "%s failed: %s\n", what, strerror(err)); | ||
| 36 | + abort(); | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +static void die(const char *what) | ||
| 40 | +{ | ||
| 41 | + die2(errno, what); | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +static void mutex_lock(pthread_mutex_t *mutex) | ||
| 45 | +{ | ||
| 46 | + int ret = pthread_mutex_lock(mutex); | ||
| 47 | + if (ret) die2(ret, "pthread_mutex_lock"); | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +static void mutex_unlock(pthread_mutex_t *mutex) | ||
| 51 | +{ | ||
| 52 | + int ret = pthread_mutex_unlock(mutex); | ||
| 53 | + if (ret) die2(ret, "pthread_mutex_unlock"); | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +static int cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | ||
| 57 | + struct timespec *ts) | ||
| 58 | +{ | ||
| 59 | + int ret = pthread_cond_timedwait(cond, mutex, ts); | ||
| 60 | + if (ret && ret != ETIMEDOUT) die2(ret, "pthread_cond_timedwait"); | ||
| 61 | + return ret; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +static void cond_broadcast(pthread_cond_t *cond) | ||
| 65 | +{ | ||
| 66 | + int ret = pthread_cond_broadcast(cond); | ||
| 67 | + if (ret) die2(ret, "pthread_cond_broadcast"); | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +static void thread_create(pthread_t *thread, pthread_attr_t *attr, | ||
| 71 | + void *(*start_routine)(void*), void *arg) | ||
| 72 | +{ | ||
| 73 | + int ret = pthread_create(thread, attr, start_routine, arg); | ||
| 74 | + if (ret) die2(ret, "pthread_create"); | ||
| 75 | +} | ||
| 76 | + | ||
| 30 | static void *aio_thread(void *unused) | 77 | static void *aio_thread(void *unused) |
| 31 | { | 78 | { |
| 32 | sigset_t set; | 79 | sigset_t set; |
| 33 | 80 | ||
| 34 | /* block all signals */ | 81 | /* block all signals */ |
| 35 | - sigfillset(&set); | ||
| 36 | - sigprocmask(SIG_BLOCK, &set, NULL); | 82 | + if (sigfillset(&set)) die("sigfillset"); |
| 83 | + if (sigprocmask(SIG_BLOCK, &set, NULL)) die("sigprocmask"); | ||
| 37 | 84 | ||
| 38 | while (1) { | 85 | while (1) { |
| 39 | struct qemu_paiocb *aiocb; | 86 | struct qemu_paiocb *aiocb; |
| 40 | size_t offset; | 87 | size_t offset; |
| 41 | int ret = 0; | 88 | int ret = 0; |
| 42 | 89 | ||
| 43 | - pthread_mutex_lock(&lock); | 90 | + mutex_lock(&lock); |
| 44 | 91 | ||
| 45 | while (TAILQ_EMPTY(&request_list) && | 92 | while (TAILQ_EMPTY(&request_list) && |
| 46 | !(ret == ETIMEDOUT)) { | 93 | !(ret == ETIMEDOUT)) { |
| @@ -49,7 +96,7 @@ static void *aio_thread(void *unused) | @@ -49,7 +96,7 @@ static void *aio_thread(void *unused) | ||
| 49 | 96 | ||
| 50 | qemu_gettimeofday(&tv); | 97 | qemu_gettimeofday(&tv); |
| 51 | ts.tv_sec = tv.tv_sec + 10; | 98 | ts.tv_sec = tv.tv_sec + 10; |
| 52 | - ret = pthread_cond_timedwait(&cond, &lock, &ts); | 99 | + ret = cond_timedwait(&cond, &lock, &ts); |
| 53 | } | 100 | } |
| 54 | 101 | ||
| 55 | if (ret == ETIMEDOUT) | 102 | if (ret == ETIMEDOUT) |
| @@ -62,7 +109,7 @@ static void *aio_thread(void *unused) | @@ -62,7 +109,7 @@ static void *aio_thread(void *unused) | ||
| 62 | aiocb->active = 1; | 109 | aiocb->active = 1; |
| 63 | 110 | ||
| 64 | idle_threads--; | 111 | idle_threads--; |
| 65 | - pthread_mutex_unlock(&lock); | 112 | + mutex_unlock(&lock); |
| 66 | 113 | ||
| 67 | while (offset < aiocb->aio_nbytes) { | 114 | while (offset < aiocb->aio_nbytes) { |
| 68 | ssize_t len; | 115 | ssize_t len; |
| @@ -89,35 +136,36 @@ static void *aio_thread(void *unused) | @@ -89,35 +136,36 @@ static void *aio_thread(void *unused) | ||
| 89 | offset += len; | 136 | offset += len; |
| 90 | } | 137 | } |
| 91 | 138 | ||
| 92 | - pthread_mutex_lock(&lock); | 139 | + mutex_lock(&lock); |
| 93 | aiocb->ret = offset; | 140 | aiocb->ret = offset; |
| 94 | idle_threads++; | 141 | idle_threads++; |
| 95 | - pthread_mutex_unlock(&lock); | 142 | + mutex_unlock(&lock); |
| 96 | 143 | ||
| 97 | - kill(getpid(), aiocb->ev_signo); | 144 | + if (kill(getpid(), aiocb->ev_signo)) die("kill failed"); |
| 98 | } | 145 | } |
| 99 | 146 | ||
| 100 | idle_threads--; | 147 | idle_threads--; |
| 101 | cur_threads--; | 148 | cur_threads--; |
| 102 | - pthread_mutex_unlock(&lock); | 149 | + mutex_unlock(&lock); |
| 103 | 150 | ||
| 104 | return NULL; | 151 | return NULL; |
| 105 | } | 152 | } |
| 106 | 153 | ||
| 107 | -static int spawn_thread(void) | 154 | +static void spawn_thread(void) |
| 108 | { | 155 | { |
| 109 | - pthread_attr_t attr; | ||
| 110 | int ret; | 156 | int ret; |
| 157 | + pthread_attr_t attr; | ||
| 111 | 158 | ||
| 112 | cur_threads++; | 159 | cur_threads++; |
| 113 | idle_threads++; | 160 | idle_threads++; |
| 114 | 161 | ||
| 115 | - pthread_attr_init(&attr); | ||
| 116 | - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | ||
| 117 | - ret = pthread_create(&thread_id, &attr, aio_thread, NULL); | ||
| 118 | - pthread_attr_destroy(&attr); | ||
| 119 | - | ||
| 120 | - return ret; | 162 | + ret = pthread_attr_init(&attr); |
| 163 | + if (ret) die2 (ret, "pthread_attr_init"); | ||
| 164 | + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | ||
| 165 | + if (ret) die2 (ret, "pthread_attr_setdetachstate"); | ||
| 166 | + thread_create(&thread_id, &attr, aio_thread, NULL); | ||
| 167 | + ret = pthread_attr_destroy(&attr); | ||
| 168 | + if (ret) die2 (ret, "pthread_attr_destroy"); | ||
| 121 | } | 169 | } |
| 122 | 170 | ||
| 123 | int qemu_paio_init(struct qemu_paioinit *aioinit) | 171 | int qemu_paio_init(struct qemu_paioinit *aioinit) |
| @@ -132,12 +180,12 @@ static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write) | @@ -132,12 +180,12 @@ static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write) | ||
| 132 | aiocb->is_write = is_write; | 180 | aiocb->is_write = is_write; |
| 133 | aiocb->ret = -EINPROGRESS; | 181 | aiocb->ret = -EINPROGRESS; |
| 134 | aiocb->active = 0; | 182 | aiocb->active = 0; |
| 135 | - pthread_mutex_lock(&lock); | 183 | + mutex_lock(&lock); |
| 136 | if (idle_threads == 0 && cur_threads < max_threads) | 184 | if (idle_threads == 0 && cur_threads < max_threads) |
| 137 | spawn_thread(); | 185 | spawn_thread(); |
| 138 | TAILQ_INSERT_TAIL(&request_list, aiocb, node); | 186 | TAILQ_INSERT_TAIL(&request_list, aiocb, node); |
| 139 | - pthread_mutex_unlock(&lock); | ||
| 140 | - pthread_cond_broadcast(&cond); | 187 | + mutex_unlock(&lock); |
| 188 | + cond_broadcast(&cond); | ||
| 141 | 189 | ||
| 142 | return 0; | 190 | return 0; |
| 143 | } | 191 | } |
| @@ -156,9 +204,9 @@ ssize_t qemu_paio_return(struct qemu_paiocb *aiocb) | @@ -156,9 +204,9 @@ ssize_t qemu_paio_return(struct qemu_paiocb *aiocb) | ||
| 156 | { | 204 | { |
| 157 | ssize_t ret; | 205 | ssize_t ret; |
| 158 | 206 | ||
| 159 | - pthread_mutex_lock(&lock); | 207 | + mutex_lock(&lock); |
| 160 | ret = aiocb->ret; | 208 | ret = aiocb->ret; |
| 161 | - pthread_mutex_unlock(&lock); | 209 | + mutex_unlock(&lock); |
| 162 | 210 | ||
| 163 | return ret; | 211 | return ret; |
| 164 | } | 212 | } |
| @@ -179,7 +227,7 @@ int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb) | @@ -179,7 +227,7 @@ int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb) | ||
| 179 | { | 227 | { |
| 180 | int ret; | 228 | int ret; |
| 181 | 229 | ||
| 182 | - pthread_mutex_lock(&lock); | 230 | + mutex_lock(&lock); |
| 183 | if (!aiocb->active) { | 231 | if (!aiocb->active) { |
| 184 | TAILQ_REMOVE(&request_list, aiocb, node); | 232 | TAILQ_REMOVE(&request_list, aiocb, node); |
| 185 | aiocb->ret = -ECANCELED; | 233 | aiocb->ret = -ECANCELED; |
| @@ -188,7 +236,7 @@ int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb) | @@ -188,7 +236,7 @@ int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb) | ||
| 188 | ret = QEMU_PAIO_NOTCANCELED; | 236 | ret = QEMU_PAIO_NOTCANCELED; |
| 189 | else | 237 | else |
| 190 | ret = QEMU_PAIO_ALLDONE; | 238 | ret = QEMU_PAIO_ALLDONE; |
| 191 | - pthread_mutex_unlock(&lock); | 239 | + mutex_unlock(&lock); |
| 192 | 240 | ||
| 193 | return ret; | 241 | return ret; |
| 194 | } | 242 | } |