semaphore.c
1 #include <darlingserver/duct-tape/semaphore.h> 2 #include <darlingserver/duct-tape/task.h> 3 4 #include <mach/semaphore.h> 5 #include <mach/task.h> 6 7 #include <stdlib.h> 8 9 dtape_semaphore_t* dtape_semaphore_create(dtape_task_t* owning_task, int initial_value) { 10 dtape_semaphore_t* semaphore = malloc(sizeof(dtape_semaphore_t)); 11 if (!semaphore) { 12 return NULL; 13 } 14 15 semaphore->owning_task = owning_task; 16 17 if (semaphore_create(&semaphore->owning_task->xnu_task, &semaphore->xnu_semaphore, 0, initial_value) != KERN_SUCCESS) { 18 free(semaphore); 19 return NULL; 20 } 21 22 return semaphore; 23 }; 24 25 void dtape_semaphore_destroy(dtape_semaphore_t* semaphore) { 26 if (semaphore_destroy(&semaphore->owning_task->xnu_task, semaphore->xnu_semaphore) != KERN_SUCCESS) { 27 panic("Failed to destroy duct-taped XNU semaphore"); 28 } 29 30 free(semaphore); 31 }; 32 33 void dtape_semaphore_up(dtape_semaphore_t* semaphore) { 34 if (semaphore_signal(semaphore->xnu_semaphore) != KERN_SUCCESS) { 35 panic("Failed to raise up-count of duct-taped XNU semaphore"); 36 } 37 }; 38 39 dtape_semaphore_wait_result_t dtape_semaphore_down(dtape_semaphore_t* semaphore) { 40 kern_return_t kr = semaphore_wait(semaphore->xnu_semaphore); 41 switch (kr) { 42 case KERN_SUCCESS: 43 return dtape_semaphore_wait_result_ok; 44 case KERN_ABORTED: 45 return dtape_semaphore_wait_result_interrupted; 46 default: 47 return dtape_semaphore_wait_result_error; 48 } 49 }; 50 51 bool dtape_semaphore_down_simple(dtape_semaphore_t* semaphore) { 52 switch (dtape_semaphore_down(semaphore)) { 53 case dtape_semaphore_wait_result_ok: 54 return true; 55 case dtape_semaphore_wait_result_interrupted: 56 return false; 57 default: 58 panic("Failed to lower up-count of duct-taped XNU semaphore"); 59 } 60 };