1 /*- 2 * Copyright (c) 2012 3 * The DragonFly Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 3. Neither the name of The DragonFly Project nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific, prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <stdlib.h> 34 #include <unistd.h> 35 36 #include "libc_private.h" 37 #include "spinlock.h" 38 39 40 struct quick_exit_fn { 41 struct quick_exit_fn *next; 42 void (*func)(void); 43 }; 44 45 static struct quick_exit_fn *quick_exit_fns; 46 static spinlock_t quick_exit_spinlock; 47 48 /* 49 * at_quick_exit: 50 * 51 * Register a function to be called at quick_exit. 52 */ 53 int 54 at_quick_exit(void (*func)(void)) 55 { 56 struct quick_exit_fn *fn; 57 58 fn = malloc(sizeof(struct quick_exit_fn)); 59 if (!fn) 60 return (-1); 61 62 fn->func = func; 63 64 if (__isthreaded) 65 _SPINLOCK(&quick_exit_spinlock); 66 67 fn->next = quick_exit_fns; 68 quick_exit_fns = fn; 69 70 if (__isthreaded) 71 _SPINUNLOCK(&quick_exit_spinlock); 72 73 return (0); 74 } 75 76 /* 77 * quick_exit: 78 * 79 * Abandon a process. Execute all quick_exit handlers. 80 */ 81 void 82 quick_exit(int status) 83 { 84 struct quick_exit_fn *fn; 85 86 if (__isthreaded) 87 _SPINLOCK(&quick_exit_spinlock); 88 for (fn = quick_exit_fns; fn != NULL; fn = fn->next) { 89 fn->func(); 90 } 91 if (__isthreaded) 92 _SPINUNLOCK(&quick_exit_spinlock); 93 94 _exit(status); 95 } 96