00001 /* Miscellaneous functions. 00002 * 00003 */ 00004 00005 #include <stdio.h> 00006 #include <stdlib.h> 00007 #include <stdarg.h> 00008 #include <pthread.h> 00009 #include <sys/time.h> 00010 #include <time.h> 00011 00012 #include "tcpproxy.h" 00013 #include "misc.h" 00014 00015 /*---------------------------------------------------------------------- 00016 * eprintf - printf, but for stderr 00017 *---------------------------------------------------------------------- 00018 */ 00019 inline void eprintf (const char *template, ...) 00020 { 00021 va_list ap; 00022 va_start (ap, template); 00023 vfprintf (stderr, template, ap); 00024 va_end (ap); 00025 } 00026 00027 /*---------------------------------------------------------------------- 00028 * xmalloc - allocates a block of memory, with error checking 00029 * exits (safely) if malloc fails. 00030 *---------------------------------------------------------------------- 00031 */ 00032 inline void *xmalloc (size_t size) 00033 { 00034 register void *val; 00035 //DPRINT("xmalloc: entered, size=%u.\n", size); 00036 val = malloc(size); 00037 if (val == NULL) { 00038 EPRINT("xmalloc: virtual memory exhausted.\n"); 00039 safe_exit(EXIT_ERR_MEM_ALLOC); 00040 } 00041 return val; 00042 } 00043 00044 /*---------------------------------------------------------------------- 00045 * xfree - deallocates a block of memory, with error checking 00046 * exits (safely) if a null pointer is given. 00047 *---------------------------------------------------------------------- 00048 */ 00049 inline void xfree(void* ptr) 00050 { 00051 //DPRINT("xfree: entered, ptr=0x%x.\n", (unsigned)ptr); 00052 if(ptr == NULL) { 00053 EPRINT("xfree: attempt to free NULL pointer.\n"); 00054 safe_exit(EXIT_ERR_MEM_FREE); 00055 } else { 00056 free(ptr); 00057 } 00058 } 00059 00060 /*---------------------------------------------------------------------- 00061 * mutex_lock - locks a mutex, with error checking 00062 * exits (safely) if the lock fails. 00063 *---------------------------------------------------------------------- 00064 */ 00065 inline void mutex_lock(char *caller, pthread_mutex_t *mut) 00066 { 00067 //DPRINT("mutex_lock: called from %s\n", caller); 00068 if(pthread_mutex_lock(mut)) { 00069 EPRINT("%s: error locking mutex.\n", caller); 00070 safe_exit(EXIT_ERR_MUTEX); 00071 } 00072 } 00073 00074 /*---------------------------------------------------------------------- 00075 * xmalloc - unlocks a mutex, with error checking 00076 * exits (safely) if the unlock fails. 00077 *---------------------------------------------------------------------- 00078 */ 00079 inline void mutex_unlock(char *caller, pthread_mutex_t *mut) 00080 { 00081 //DPRINT("mutex_unlock: called from %s\n", caller); 00082 if(pthread_mutex_unlock(mut)) { 00083 EPRINT("%s: error unlocking mutex.\n", caller); 00084 safe_exit(EXIT_ERR_MUTEX); 00085 } 00086 } 00087 00088 /*---------------------------------------------------------------------- 00089 * get_uclock - returns the number of microseconds since the Epoch 00090 * (modulo MAX_LONG_INT). 00091 *---------------------------------------------------------------------- 00092 */ 00093 inline long get_uclock() 00094 { 00095 struct timeval tv; 00096 gettimeofday(&tv, 0); 00097 return (tv.tv_sec*1000000 + tv.tv_usec); 00098 } 00099 00100 /*---------------------------------------------------------------------- 00101 * get_mclock - returns the number of milliseconds since the Epoch 00102 * (modulo MAX_LONG_INT). 00103 *---------------------------------------------------------------------- 00104 */ 00105 inline long get_mclock() 00106 { 00107 struct timeval tv; 00108 gettimeofday(&tv, 0); 00109 return (tv.tv_sec*1000 + tv.tv_usec/1000); 00110 } 00111 00112 /*---------------------------------------------------------------------- 00113 * safe_exit - performs a safe exit from the program, no matter who 00114 * calls it. If called from the 'main' thread, the exit 00115 * command is used. If called from a thread, the main 00116 * thread is signalled to exit with a SIGTERM. 00117 *---------------------------------------------------------------------- 00118 */ 00119 void safe_exit(int val) 00120 { 00121 pthread_t self = pthread_self(); 00122 00123 request_exit = val; 00124 00125 if(pthread_equal(self, main_thread)) { 00126 exit(val); 00127 } else { 00128 pthread_kill(main_thread, SIGTERM); 00129 pthread_exit(NULL); 00130 } 00131 } 00132 00133 /*---------------------------------------------------------------------- 00134 * ceil_div - returns the ceiling of the division a / b 00135 *---------------------------------------------------------------------- 00136 */ 00137 inline unsigned ceil_div(unsigned a, unsigned b) 00138 { 00139 return (a/b) + (a%b ? 1 : 0); 00140 }