161 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "inc.h"
 | |
| 
 | |
| int identifier = 0x1234;
 | |
| endpoint_t who_e;
 | |
| int call_type;
 | |
| 
 | |
| static struct {
 | |
| 	int type;
 | |
| 	int (*func)(message *);
 | |
| 	int reply;	/* whether the reply action is passed through */
 | |
| } ipc_calls[] = {
 | |
| 	{ IPC_SHMGET,	do_shmget,	0 },
 | |
| 	{ IPC_SHMAT,	do_shmat,	0 },
 | |
| 	{ IPC_SHMDT,	do_shmdt,	0 },
 | |
| 	{ IPC_SHMCTL,	do_shmctl,	0 },
 | |
| 	{ IPC_SEMGET,	do_semget,	0 },
 | |
| 	{ IPC_SEMCTL,	do_semctl,	0 },
 | |
| 	{ IPC_SEMOP,	do_semop,	1 },
 | |
| };
 | |
| 
 | |
| #define SIZE(a) (sizeof(a)/sizeof(a[0]))
 | |
| 
 | |
| static int verbose = 0;
 | |
| 
 | |
| /* SEF functions and variables. */
 | |
| static void sef_local_startup(void);
 | |
| static int sef_cb_init_fresh(int type, sef_init_info_t *info);
 | |
| static void sef_cb_signal_handler(int signo);
 | |
| 
 | |
| int main(int argc, char *argv[])
 | |
| {
 | |
| 	message m;
 | |
| 
 | |
| 	/* SEF local startup. */
 | |
| 	env_setargs(argc, argv);
 | |
| 	sef_local_startup();
 | |
| 
 | |
| 	while (TRUE) {
 | |
| 		int r;
 | |
| 		int ipc_number;
 | |
| 
 | |
| 		if ((r = sef_receive(ANY, &m)) != OK)
 | |
| 			printf("sef_receive failed %d.\n", r);
 | |
| 		who_e = m.m_source;
 | |
| 		call_type = m.m_type;
 | |
| 
 | |
| 		if(verbose)
 | |
| 			printf("IPC: get %d from %d\n", call_type, who_e);
 | |
| 
 | |
| 		if (call_type & NOTIFY_MESSAGE) {
 | |
| 			switch (who_e) {
 | |
| 			case VM_PROC_NR:
 | |
| 				/* currently, only semaphore needs such information. */
 | |
| 				sem_process_vm_notify();
 | |
| 				break;
 | |
| 			default:
 | |
| 				printf("IPC: ignoring notify() from %d\n",
 | |
| 					who_e);
 | |
| 				break;
 | |
| 			}
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		/*
 | |
| 		 * The ipc number in the table can be obtained
 | |
| 		 * with a simple equation because the values of
 | |
| 		 * IPC system calls are consecutive and begin
 | |
| 		 * at ( IPC_BASE + 1 )
 | |
| 		 */
 | |
| 
 | |
| 		ipc_number = call_type - (IPC_BASE + 1);
 | |
| 
 | |
| 		/* dispatch message */
 | |
| 		if (ipc_number >= 0 && ipc_number < SIZE(ipc_calls)) {
 | |
| 			int result;
 | |
| 
 | |
| 			if (ipc_calls[ipc_number].type != call_type)
 | |
| 				panic("IPC: call table order mismatch");
 | |
| 
 | |
| 			/* If any process does an IPC call,
 | |
| 			 * we have to know about it exiting.
 | |
| 			 * Tell VM to watch it for us.
 | |
| 			 */
 | |
| 			if(vm_watch_exit(m.m_source) != OK) {
 | |
| 				printf("IPC: watch failed on %d\n", m.m_source);
 | |
| 			}
 | |
| 
 | |
| 			result = ipc_calls[ipc_number].func(&m);
 | |
| 
 | |
| 			/*
 | |
| 			 * The handler of the IPC call did not
 | |
| 			 * post a reply.
 | |
| 			 */
 | |
| 			if (!ipc_calls[ipc_number].reply) {
 | |
| 
 | |
| 				m.m_type = result;
 | |
| 
 | |
| 				if(verbose && result != OK)
 | |
| 					printf("IPC: error for %d: %d\n",
 | |
| 						call_type, result);
 | |
| 
 | |
| 				if ((r = ipc_sendnb(who_e, &m)) != OK)
 | |
| 					printf("IPC send error %d.\n", r);
 | |
| 			}
 | |
| 		} else {
 | |
| 			/* warn and then ignore */
 | |
| 			printf("IPC unknown call type: %d from %d.\n",
 | |
| 				call_type, who_e);
 | |
| 		}
 | |
| 		update_refcount_and_destroy();
 | |
| 	}
 | |
| 
 | |
| 	/* no way to get here */
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *			       sef_local_startup			     *
 | |
|  *===========================================================================*/
 | |
| static void sef_local_startup()
 | |
| {
 | |
|   /* Register init callbacks. */
 | |
|   sef_setcb_init_fresh(sef_cb_init_fresh);
 | |
|   sef_setcb_init_restart(sef_cb_init_fresh);
 | |
| 
 | |
|   /* No live update support for now. */
 | |
| 
 | |
|   /* Register signal callbacks. */
 | |
|   sef_setcb_signal_handler(sef_cb_signal_handler);
 | |
| 
 | |
|   /* Let SEF perform startup. */
 | |
|   sef_startup();
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *		            sef_cb_init_fresh                                *
 | |
|  *===========================================================================*/
 | |
| static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 | |
| {
 | |
| /* Initialize the ipc server. */
 | |
| 
 | |
|   if(verbose)
 | |
|       printf("IPC: self: %d\n", sef_self());
 | |
| 
 | |
|   return(OK);
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *		            sef_cb_signal_handler                            *
 | |
|  *===========================================================================*/
 | |
| static void sef_cb_signal_handler(int signo)
 | |
| {
 | |
|   /* Only check for termination signal, ignore anything else. */
 | |
|   if (signo != SIGTERM) return;
 | |
| 
 | |
|   /* Checkout if there are still IPC keys. Inform the user in that case. */
 | |
|   if (!is_sem_nil() || !is_shm_nil())
 | |
|       printf("IPC: exit with un-clean states.\n");
 | |
| }
 | |
| 
 | 
