Error checking
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6630 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									5518f3a636
								
							
						
					
					
						commit
						8653c0158c
					
				| @ -15,6 +15,9 @@ | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <sys/time.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include "osdep.h" | ||||
| 
 | ||||
| #include "posix-aio-compat.h" | ||||
| @ -27,20 +30,64 @@ static int cur_threads = 0; | ||||
| static int idle_threads = 0; | ||||
| static TAILQ_HEAD(, qemu_paiocb) request_list; | ||||
| 
 | ||||
| static void die2(int err, const char *what) | ||||
| { | ||||
|     fprintf(stderr, "%s failed: %s\n", what, strerror(err)); | ||||
|     abort(); | ||||
| } | ||||
| 
 | ||||
| static void die(const char *what) | ||||
| { | ||||
|     die2(errno, what); | ||||
| } | ||||
| 
 | ||||
| static void mutex_lock(pthread_mutex_t *mutex) | ||||
| { | ||||
|     int ret = pthread_mutex_lock(mutex); | ||||
|     if (ret) die2(ret, "pthread_mutex_lock"); | ||||
| } | ||||
| 
 | ||||
| static void mutex_unlock(pthread_mutex_t *mutex) | ||||
| { | ||||
|     int ret = pthread_mutex_unlock(mutex); | ||||
|     if (ret) die2(ret, "pthread_mutex_unlock"); | ||||
| } | ||||
| 
 | ||||
| static int cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
|                            struct timespec *ts) | ||||
| { | ||||
|     int ret = pthread_cond_timedwait(cond, mutex, ts); | ||||
|     if (ret && ret != ETIMEDOUT) die2(ret, "pthread_cond_timedwait"); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static void cond_broadcast(pthread_cond_t *cond) | ||||
| { | ||||
|     int ret = pthread_cond_broadcast(cond); | ||||
|     if (ret) die2(ret, "pthread_cond_broadcast"); | ||||
| } | ||||
| 
 | ||||
| static void thread_create(pthread_t *thread, pthread_attr_t *attr, | ||||
|                           void *(*start_routine)(void*), void *arg) | ||||
| { | ||||
|     int ret = pthread_create(thread, attr, start_routine, arg); | ||||
|     if (ret) die2(ret, "pthread_create"); | ||||
| } | ||||
| 
 | ||||
| static void *aio_thread(void *unused) | ||||
| { | ||||
|     sigset_t set; | ||||
| 
 | ||||
|     /* block all signals */ | ||||
|     sigfillset(&set); | ||||
|     sigprocmask(SIG_BLOCK, &set, NULL); | ||||
|     if (sigfillset(&set)) die("sigfillset"); | ||||
|     if (sigprocmask(SIG_BLOCK, &set, NULL)) die("sigprocmask"); | ||||
| 
 | ||||
|     while (1) { | ||||
|         struct qemu_paiocb *aiocb; | ||||
|         size_t offset; | ||||
|         int ret = 0; | ||||
| 
 | ||||
|         pthread_mutex_lock(&lock); | ||||
|         mutex_lock(&lock); | ||||
| 
 | ||||
|         while (TAILQ_EMPTY(&request_list) && | ||||
|                !(ret == ETIMEDOUT)) { | ||||
| @ -49,7 +96,7 @@ static void *aio_thread(void *unused) | ||||
| 
 | ||||
|             qemu_gettimeofday(&tv); | ||||
|             ts.tv_sec = tv.tv_sec + 10; | ||||
|             ret = pthread_cond_timedwait(&cond, &lock, &ts); | ||||
|             ret = cond_timedwait(&cond, &lock, &ts); | ||||
|         } | ||||
| 
 | ||||
|         if (ret == ETIMEDOUT) | ||||
| @ -62,7 +109,7 @@ static void *aio_thread(void *unused) | ||||
|         aiocb->active = 1; | ||||
| 
 | ||||
|         idle_threads--; | ||||
|         pthread_mutex_unlock(&lock); | ||||
|         mutex_unlock(&lock); | ||||
| 
 | ||||
|         while (offset < aiocb->aio_nbytes) { | ||||
|             ssize_t len; | ||||
| @ -89,35 +136,36 @@ static void *aio_thread(void *unused) | ||||
|             offset += len; | ||||
|         } | ||||
| 
 | ||||
|         pthread_mutex_lock(&lock); | ||||
|         mutex_lock(&lock); | ||||
|         aiocb->ret = offset; | ||||
|         idle_threads++; | ||||
|         pthread_mutex_unlock(&lock); | ||||
|         mutex_unlock(&lock); | ||||
| 
 | ||||
|         kill(getpid(), aiocb->ev_signo); | ||||
|         if (kill(getpid(), aiocb->ev_signo)) die("kill failed"); | ||||
|     } | ||||
| 
 | ||||
|     idle_threads--; | ||||
|     cur_threads--; | ||||
|     pthread_mutex_unlock(&lock); | ||||
|     mutex_unlock(&lock); | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static int spawn_thread(void) | ||||
| static void spawn_thread(void) | ||||
| { | ||||
|     pthread_attr_t attr; | ||||
|     int ret; | ||||
|     pthread_attr_t attr; | ||||
| 
 | ||||
|     cur_threads++; | ||||
|     idle_threads++; | ||||
| 
 | ||||
|     pthread_attr_init(&attr); | ||||
|     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | ||||
|     ret = pthread_create(&thread_id, &attr, aio_thread, NULL); | ||||
|     pthread_attr_destroy(&attr); | ||||
| 
 | ||||
|     return ret; | ||||
|     ret = pthread_attr_init(&attr); | ||||
|     if (ret) die2 (ret, "pthread_attr_init"); | ||||
|     ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | ||||
|     if (ret) die2 (ret, "pthread_attr_setdetachstate"); | ||||
|     thread_create(&thread_id, &attr, aio_thread, NULL); | ||||
|     ret = pthread_attr_destroy(&attr); | ||||
|     if (ret) die2 (ret, "pthread_attr_destroy"); | ||||
| } | ||||
| 
 | ||||
| int qemu_paio_init(struct qemu_paioinit *aioinit) | ||||
| @ -132,12 +180,12 @@ static int qemu_paio_submit(struct qemu_paiocb *aiocb, int is_write) | ||||
|     aiocb->is_write = is_write; | ||||
|     aiocb->ret = -EINPROGRESS; | ||||
|     aiocb->active = 0; | ||||
|     pthread_mutex_lock(&lock); | ||||
|     mutex_lock(&lock); | ||||
|     if (idle_threads == 0 && cur_threads < max_threads) | ||||
|         spawn_thread(); | ||||
|     TAILQ_INSERT_TAIL(&request_list, aiocb, node); | ||||
|     pthread_mutex_unlock(&lock); | ||||
|     pthread_cond_broadcast(&cond); | ||||
|     mutex_unlock(&lock); | ||||
|     cond_broadcast(&cond); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| @ -156,9 +204,9 @@ ssize_t qemu_paio_return(struct qemu_paiocb *aiocb) | ||||
| { | ||||
|     ssize_t ret; | ||||
| 
 | ||||
|     pthread_mutex_lock(&lock); | ||||
|     mutex_lock(&lock); | ||||
|     ret = aiocb->ret; | ||||
|     pthread_mutex_unlock(&lock); | ||||
|     mutex_unlock(&lock); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| @ -179,7 +227,7 @@ int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb) | ||||
| { | ||||
|     int ret; | ||||
| 
 | ||||
|     pthread_mutex_lock(&lock); | ||||
|     mutex_lock(&lock); | ||||
|     if (!aiocb->active) { | ||||
|         TAILQ_REMOVE(&request_list, aiocb, node); | ||||
|         aiocb->ret = -ECANCELED; | ||||
| @ -188,7 +236,7 @@ int qemu_paio_cancel(int fd, struct qemu_paiocb *aiocb) | ||||
|         ret = QEMU_PAIO_NOTCANCELED; | ||||
|     else | ||||
|         ret = QEMU_PAIO_ALLDONE; | ||||
|     pthread_mutex_unlock(&lock); | ||||
|     mutex_unlock(&lock); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 malc
						malc