| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | /*
 | 
					
						
							|  |  |  | Looking Glass - KVM FrameRelay (KVMFR) Client | 
					
						
							|  |  |  | Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com> | 
					
						
							|  |  |  | https://looking-glass.hostfission.com
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 2 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, write to the Free Software Foundation, Inc., 59 Temple | 
					
						
							|  |  |  | Place, Suite 330, Boston, MA 02111-1307 USA | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 19:07:23 +10:00
										 |  |  | #include "interface/platform.h"
 | 
					
						
							|  |  |  | #include "common/debug.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  | #include "common/option.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-09 19:07:23 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | #include <getopt.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <sys/mman.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-01 12:54:15 +11:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-01 12:54:15 +11:00
										 |  |  | #include <pthread.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-02 20:31:33 +11:00
										 |  |  | #include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-01 12:54:15 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | struct app | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-11 17:15:17 +10:00
										 |  |  |   const char  * executable; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   unsigned int  shmSize; | 
					
						
							|  |  |  |   int           shmFD; | 
					
						
							|  |  |  |   void        * shmMap; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct app app; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 12:54:15 +11:00
										 |  |  | struct osThreadHandle | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const char       * name; | 
					
						
							|  |  |  |   osThreadFunction   function; | 
					
						
							|  |  |  |   void             * opaque; | 
					
						
							|  |  |  |   pthread_t          handle; | 
					
						
							|  |  |  |   int                resultCode; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-02 20:31:33 +11:00
										 |  |  | void sigHandler(int signo) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   DEBUG_INFO("SIGINT"); | 
					
						
							|  |  |  |   app_quit(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | int main(int argc, char * argv[]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-11 17:15:17 +10:00
										 |  |  |   app.executable = argv[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |   struct Option options[] = | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |     { | 
					
						
							|  |  |  |       .module      = "os", | 
					
						
							|  |  |  |       .name        = "shmDevice", | 
					
						
							|  |  |  |       .description = "The IVSHMEM device to use", | 
					
						
							|  |  |  |       .value       = { | 
					
						
							|  |  |  |         .type       = OPTION_TYPE_STRING, | 
					
						
							|  |  |  |         .v.x_string = "uio0" | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       .validator   = NULL, | 
					
						
							|  |  |  |       .printHelp   = NULL | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     {0} | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |   option_register(options); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |   int result = app_main(argc, argv); | 
					
						
							|  |  |  |   os_shmemUnmap(); | 
					
						
							|  |  |  |   close(app.shmFD); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool app_init() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const char * shmDevice = option_get_string("os", "shmDevice"); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  |   // check the deice name
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     char file[100] = "/sys/class/uio/"; | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |     strncat(file, shmDevice, sizeof(file) - 1); | 
					
						
							|  |  |  |     strncat(file, "/name"  , sizeof(file) - 1); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int fd = open(file, O_RDONLY); | 
					
						
							|  |  |  |     if (fd < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       DEBUG_ERROR("Failed to open: %s", file); | 
					
						
							|  |  |  |       DEBUG_ERROR("Did you remmeber to modprobe the kvmfr module?"); | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char name[32]; | 
					
						
							|  |  |  |     int len = read(fd, name, sizeof(name) - 1); | 
					
						
							|  |  |  |     if (len <= 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       DEBUG_ERROR("Failed to read: %s", file); | 
					
						
							|  |  |  |       close(fd); | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  |     } | 
					
						
							|  |  |  |     name[len] = '\0'; | 
					
						
							|  |  |  |     close(fd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:17:16 +11:00
										 |  |  |     while(len > 0 && name[len-1] == '\n') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       --len; | 
					
						
							|  |  |  |       name[len] = '\0'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  |     if (strcmp(name, "KVMFR") != 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-03-01 21:17:16 +11:00
										 |  |  |       DEBUG_ERROR("Device is not a KVMFR device \"%s\" reports as: %s", file, name); | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   // get the device size
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     char file[100] = "/sys/class/uio/"; | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |     strncat(file, shmDevice        , sizeof(file) - 1); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:03:10 +11:00
										 |  |  |     strncat(file, "/maps/map0/size", sizeof(file) - 1); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int fd = open(file, O_RDONLY); | 
					
						
							|  |  |  |     if (fd < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       DEBUG_ERROR("Failed to open: %s", file); | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char size[32]; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:12:42 +11:00
										 |  |  |     int  len = read(fd, size, sizeof(size) - 1); | 
					
						
							|  |  |  |     if (len <= 0) | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |     { | 
					
						
							|  |  |  |       DEBUG_ERROR("Failed to read: %s", file); | 
					
						
							|  |  |  |       close(fd); | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |     } | 
					
						
							|  |  |  |     size[len] = '\0'; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:11:44 +11:00
										 |  |  |     close(fd); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     app.shmSize = strtoul(size, NULL, 16); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // open the device
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     char file[100] = "/dev/"; | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |     strncat(file, shmDevice, sizeof(file) - 1); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |     app.shmFD   = open(file, O_RDWR, (mode_t)0600); | 
					
						
							|  |  |  |     app.shmMap  = MAP_FAILED; | 
					
						
							|  |  |  |     if (app.shmFD < 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       DEBUG_ERROR("Failed to open: %s", file); | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-03-01 21:17:16 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |     DEBUG_INFO("KVMFR Device     : %s", file); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-02 20:31:33 +11:00
										 |  |  |   signal(SIGINT, sigHandler); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 17:15:17 +10:00
										 |  |  | const char * os_getExecutable() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return app.executable; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | unsigned int os_shmemSize() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   return app.shmSize; | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool os_shmemMmap(void **ptr) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   if (app.shmMap == MAP_FAILED) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     app.shmMap = mmap(0, app.shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, app.shmFD, 0); | 
					
						
							|  |  |  |     if (app.shmMap == MAP_FAILED) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-05-09 22:06:58 +10:00
										 |  |  |       const char * shmDevice = option_get_string("os", "shmDevice"); | 
					
						
							|  |  |  |       DEBUG_ERROR("Failed to map the shared memory device: %s", shmDevice); | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *ptr = app.shmMap; | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void os_shmemUnmap() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-01 21:01:25 +11:00
										 |  |  |   if (app.shmMap == MAP_FAILED) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   munmap(app.shmMap, app.shmSize); | 
					
						
							|  |  |  |   app.shmMap = MAP_FAILED; | 
					
						
							| 
									
										
										
										
											2019-03-01 12:54:15 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void * threadWrapper(void * opaque) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   osThreadHandle * handle = (osThreadHandle *)opaque; | 
					
						
							|  |  |  |   handle->resultCode = handle->function(handle->opaque); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool os_createThread(const char * name, osThreadFunction function, void * opaque, osThreadHandle ** handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   *handle = (osThreadHandle*)malloc(sizeof(osThreadHandle)); | 
					
						
							|  |  |  |   (*handle)->name     = name; | 
					
						
							|  |  |  |   (*handle)->function = function; | 
					
						
							|  |  |  |   (*handle)->opaque   = opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_create(&(*handle)->handle, NULL, threadWrapper, *handle) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("pthread_create failed for thread: %s", name); | 
					
						
							|  |  |  |     free(*handle); | 
					
						
							|  |  |  |     *handle = NULL; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool os_joinThread(osThreadHandle * handle, int * resultCode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (pthread_join(handle->handle, NULL) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("pthread_join failed for thread: %s", handle->name); | 
					
						
							|  |  |  |     free(handle); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (resultCode) | 
					
						
							|  |  |  |     *resultCode = handle->resultCode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   free(handle); | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct osEventHandle | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_mutex_t mutex; | 
					
						
							|  |  |  |   pthread_cond_t  cond; | 
					
						
							|  |  |  |   bool            flag; | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  |   bool            autoReset; | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  | osEventHandle * os_createEvent(bool autoReset) | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   osEventHandle * handle = (osEventHandle *)calloc(sizeof(osEventHandle), 1); | 
					
						
							|  |  |  |   if (!handle) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to allocate memory"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_init(&handle->mutex, NULL) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to create the mutex"); | 
					
						
							|  |  |  |     free(handle); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_cond_init(&handle->cond, NULL) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     pthread_mutex_destroy(&handle->mutex); | 
					
						
							|  |  |  |     free(handle); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  |   handle->autoReset = autoReset; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  |   return handle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void os_freeEvent(osEventHandle * handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   assert(handle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pthread_cond_destroy (&handle->cond ); | 
					
						
							|  |  |  |   pthread_mutex_destroy(&handle->mutex); | 
					
						
							|  |  |  |   free(handle); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  | bool os_waitEvent(osEventHandle * handle, unsigned int timeout) | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  | { | 
					
						
							|  |  |  |   assert(handle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_lock(&handle->mutex) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to lock the mutex"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while(!handle->flag) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  |     if (timeout == TIMEOUT_INFINITE) | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  |       if (pthread_cond_wait(&handle->cond, &handle->mutex) != 0) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         DEBUG_ERROR("Wait to wait on the condition"); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       struct timespec ts; | 
					
						
							|  |  |  |       ts.tv_sec  = timeout / 1000; | 
					
						
							|  |  |  |       ts.tv_nsec = (timeout % 1000) * 1000000; | 
					
						
							|  |  |  |       switch(pthread_cond_timedwait(&handle->cond, &handle->mutex, &ts)) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         case ETIMEDOUT: | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |           DEBUG_ERROR("Timed wait failed"); | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  |   if (handle->autoReset) | 
					
						
							|  |  |  |     handle->flag = false; | 
					
						
							| 
									
										
										
										
											2019-03-02 20:22:35 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_unlock(&handle->mutex) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to unlock the mutex"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool os_signalEvent(osEventHandle * handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   assert(handle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_lock(&handle->mutex) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to lock the mutex"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   handle->flag = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_unlock(&handle->mutex) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to unlock the mutex"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_cond_signal(&handle->cond) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to signal the condition"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 17:08:49 +11:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool os_resetEvent(osEventHandle * handle) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   assert(handle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_lock(&handle->mutex) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to lock the mutex"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   handle->flag = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pthread_mutex_unlock(&handle->mutex) != 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DEBUG_ERROR("Failed to unlock the mutex"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-01 12:54:15 +11:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2019-02-28 19:31:04 +11:00
										 |  |  | } |