00001 #include "bcipc.h"
00002 #include "bcresources.h"
00003 #include "bcsignals.h"
00004 #include "sema.h"
00005 #include <signal.h>
00006 #include <stdlib.h>
00007 #include <sys/sem.h>
00008 #include <sys/msg.h>
00009 #include <sys/shm.h>
00010
00011
00012
00013
00014
00015 static ArrayList<int> global_shmem_db;
00016 static ArrayList<int> global_sema_db;
00017 static ArrayList<int> global_msg_db;
00018 static Mutex global_ipc_lock;
00019 static int crashed = 0;
00020
00021
00022
00023 int bc_enter_id(ArrayList<int>* list, int id);
00024 int bc_remove_id(ArrayList<int>* list, int id);
00025
00026 void bc_ipc_termination(int signum)
00027 {
00028 global_ipc_lock.lock();
00029
00030
00031 if(!crashed)
00032 {
00033
00034 #if 0
00035 union semun arg;
00036 int i;
00037
00038 if(global_shmem_db.total || global_sema_db.total || global_msg_db.total)
00039 printf("Crash\n");
00040 for(i = 0; i < global_shmem_db.total; i++)
00041 {
00042 if(!shmctl(global_shmem_db.values[i], IPC_RMID, NULL))
00043 {
00044 printf("Deleted shared memory %d\n", global_shmem_db.values[i]);
00045 }
00046 }
00047
00048 for(i = 0; i < global_sema_db.total; i++)
00049 {
00050 if(!semctl(global_sema_db.values[i], 0, IPC_RMID, arg))
00051 {
00052 printf("Deleted semaphore %d\n", global_sema_db.values[i]);
00053 }
00054 }
00055
00056 for(i = 0; i < global_msg_db.total; i++)
00057 {
00058 if(!msgctl(global_msg_db.values[i], IPC_RMID, NULL))
00059 {
00060 printf("Deleted message %d\n", global_msg_db.values[i]);
00061 }
00062 }
00063
00064 global_shmem_db.remove_all();
00065 global_sema_db.remove_all();
00066 global_msg_db.remove_all();
00067
00068
00069
00070 #endif
00071
00072
00073
00074 if(BC_Resources::signal_handler)
00075 BC_Resources::signal_handler->signal_handler(signum);
00076 crashed = 1;
00077 }
00078 global_ipc_lock.unlock();
00079 exit(0);
00080 }
00081
00082 int bc_init_ipc()
00083 {
00084 if(signal(SIGSEGV, bc_ipc_termination) == SIG_IGN)
00085 signal(SIGSEGV, SIG_IGN);
00086 if(signal(SIGBUS, bc_ipc_termination) == SIG_IGN)
00087 signal(SIGBUS, SIG_IGN);
00088
00089
00090
00091 if(signal(SIGINT, bc_ipc_termination) == SIG_IGN)
00092 signal(SIGINT, SIG_IGN);
00093 if(signal(SIGHUP, bc_ipc_termination) == SIG_IGN)
00094 signal(SIGHUP, SIG_IGN);
00095 if(signal(SIGTERM, bc_ipc_termination) == SIG_IGN)
00096 signal(SIGTERM, SIG_IGN);
00097 return 0;
00098 }
00099
00100
00101 int bc_enter_shmem_id(int id)
00102 {
00103 return bc_enter_id(&global_shmem_db, id);
00104 }
00105
00106 int bc_remove_shmem_id(int id)
00107 {
00108 return bc_remove_id(&global_shmem_db, id);
00109 }
00110
00111 int bc_enter_sema_id(int id)
00112 {
00113 return bc_enter_id(&global_sema_db, id);
00114 }
00115
00116 int bc_remove_sema_id(int id)
00117 {
00118 return bc_remove_id(&global_sema_db, id);
00119 }
00120
00121 int bc_enter_msg_id(int id)
00122 {
00123 return bc_enter_id(&global_msg_db, id);
00124 }
00125
00126 int bc_remove_msg_id(int id)
00127 {
00128 return bc_remove_id(&global_msg_db, id);
00129 }
00130
00131 int bc_enter_id(ArrayList<int>* list, int id)
00132 {
00133 int i, result = 0;
00134 global_ipc_lock.lock();
00135 for(i = 0; i < list->total; i++)
00136 {
00137 if(list->values[i] == id) result = 1;
00138 }
00139 if(!result) list->append(id);
00140 global_ipc_lock.unlock();
00141 return 0;
00142 }
00143
00144 int bc_remove_id(ArrayList<int>* list, int id)
00145 {
00146 int i;
00147 global_ipc_lock.lock();
00148 for(i = 0; i < list->total; i++)
00149 {
00150 if(list->values[i] == id) list->remove_number(i);
00151 }
00152 global_ipc_lock.unlock();
00153 return 0;
00154 }
00155