PRIVATE void dispatcher_thread(void *unused) { /* * Gets all messages and dispatches them. * * NOTE: this thread runs only when no other ddekit is * ready. So please take care that youre threads * leave some time for the others! */ message m; int r; int i; _ddekit_thread_set_myprio(0); for( ; ; ) { /* Trigger a timer interrupt at each loop iteration */ _ddekit_timer_update(); /* Wait for messages */ if ((r = sef_receive(ANY, &m)) != 0) { ddekit_panic("ddekit", "sef_receive failed", r); } _ddekit_timer_interrupt(); _ddekit_thread_wakeup_sleeping(); if (is_notify(m.m_type)) { switch (_ENDPOINT_P(m.m_source)) { case HARDWARE: for (i =0 ; i < 32 ; i++) { if(m.NOTIFY_ARG & (1 << i)) { _ddekit_interrupt_trigger(i); } } break; case CLOCK: _ddekit_timer_pending = 0; break; default: ddekit_thread_schedule(); } } else { /* * I don't know how to handle this msg, * but maybe we have a msg queue which can * handle this msg. */ ddekit_minix_queue_msg(&m); } } }
/*===========================================================================* * get_work * *===========================================================================*/ static void get_work() { int status = 0; status = sef_receive(ANY, &m_in); /* this blocks until message arrives */ if (OK != status) panic("sef_receive failed!: %d", status); who_e = m_in.m_source; /* message arrived! set sender */ callnr = m_in.m_type; /* set function call number */ }
/*===========================================================================* * get_work * *===========================================================================*/ PRIVATE void get_work( message *m_ptr /* message buffer */ ) { int status = sef_receive(ANY, m_ptr); /* blocks until message arrives */ if (OK != status) panic("failed to receive message!: %d", status); who_e = m_ptr->m_source; /* message arrived! set sender */ callnr = m_ptr->m_type; /* set function call number */ }
/*===========================================================================* * get_work * *===========================================================================*/ PRIVATE int get_work(void) { /* Retrieve work. Return the call number. */ int r; if ((r = sef_receive(ANY, &fs_m_in)) != OK) panic(__FILE__, "receive failed", r); return fs_m_in.m_type; }
/*===========================================================================* * get_work * *===========================================================================*/ static int get_work(void) { /* Normally wait for new input. However, if 'reviving' is nonzero, a * suspended process must be awakened. Return TRUE if there is a message to * process (usually newly received, but possibly a resumed request), or FALSE * if a thread for other activities has been spawned instead. */ int r, proc_p; register struct fproc *rp; if (reviving != 0) { /* Find a suspended process. */ for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) if (rp->fp_pid != PID_FREE && (rp->fp_flags & FP_REVIVED)) return unblock(rp); /* So main loop can process job */ panic("VFS: get_work couldn't revive anyone"); } for(;;) { /* Normal case. No one to revive. Get a useful request. */ if ((r = sef_receive(ANY, &m_in)) != OK) { panic("VFS: sef_receive error: %d", r); } proc_p = _ENDPOINT_P(m_in.m_source); if (proc_p < 0 || proc_p >= NR_PROCS) fp = NULL; else fp = &fproc[proc_p]; /* Negative who_p is never used to access the fproc array. Negative * numbers (kernel tasks) are treated in a special way. */ if (fp && fp->fp_endpoint == NONE) { printf("VFS: ignoring request from %d: NONE endpoint %d (%d)\n", m_in.m_source, who_p, m_in.m_type); continue; } /* Internal consistency check; our mental image of process numbers and * endpoints must match with how the rest of the system thinks of them. */ if (fp && fp->fp_endpoint != who_e) { if (fproc[who_p].fp_endpoint == NONE) printf("slot unknown even\n"); panic("VFS: receive endpoint inconsistent (source %d, who_p " "%d, stored ep %d, who_e %d).\n", m_in.m_source, who_p, fproc[who_p].fp_endpoint, who_e); } return TRUE; } /* NOTREACHED */ }
int main(int argc, char **argv) { message m; int r; env_setargs(argc, argv); sef_local_startup(); for (;;) { if ((r = sef_receive(ANY, &m)) != OK) panic("sef_receive failed (%d)\n", r); m.m_type = do_request(&m); send(m.m_source, &m); } return 0; }
/*===========================================================================* * get_work * *===========================================================================*/ static void get_work() { /* Normally wait for new input. However, if 'reviving' is * nonzero, a suspended process must be awakened. */ int r, found_one, proc_p; register struct fproc *rp; while (reviving != 0) { found_one = FALSE; /* Find a suspended process. */ for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) if (rp->fp_pid != PID_FREE && (rp->fp_flags & FP_REVIVED)) { found_one = TRUE; /* Found a suspended process */ if (unblock(rp)) return; /* So main loop can process job */ send_work(); } if (!found_one) /* Consistency error */ panic("VFS: get_work couldn't revive anyone"); } for(;;) { /* Normal case. No one to revive. Get a useful request. */ if ((r = sef_receive(receive_from, &m_in)) != OK) { panic("VFS: sef_receive error: %d", r); } proc_p = _ENDPOINT_P(m_in.m_source); if (proc_p < 0) fp = NULL; else fp = &fproc[proc_p]; if (m_in.m_type == EDEADSRCDST) return; /* Failed 'sendrec' */ /* Negative who_p is never used to access the fproc array. Negative * numbers (kernel tasks) are treated in a special way. */ if (who_p >= (int)(sizeof(fproc) / sizeof(struct fproc))) panic("receive process out of range: %d", who_p); if (who_p >= 0 && fproc[who_p].fp_endpoint == NONE) { printf("VFS: ignoring request from %d: NONE endpoint %d (%d)\n", m_in.m_source, who_p, m_in.m_type); continue; } /* Internal consistency check; our mental image of process numbers and * endpoints must match with how the rest of the system thinks of them. */ if (who_p >= 0 && fproc[who_p].fp_endpoint != who_e) { if (fproc[who_p].fp_endpoint == NONE) printf("slot unknown even\n"); printf("VFS: receive endpoint inconsistent (source %d, who_p " "%d, stored ep %d, who_e %d).\n", m_in.m_source, who_p, fproc[who_p].fp_endpoint, who_e); panic("VFS: inconsistent endpoint "); } return; } }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info) { /* Initialize the virtual file server. */ int s, i; struct fproc *rfp; message mess; struct rprocpub rprocpub[NR_BOOT_PROCS]; force_sync = 0; receive_from = ANY; self = NULL; verbose = 0; /* Initialize proc endpoints to NONE */ for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { rfp->fp_endpoint = NONE; rfp->fp_pid = PID_FREE; } /* Initialize the process table with help of the process manager messages. * Expect one message for each system process with its slot number and pid. * When no more processes follow, the magic process number NONE is sent. * Then, stop and synchronize with the PM. */ do { if ((s = sef_receive(PM_PROC_NR, &mess)) != OK) panic("VFS: couldn't receive from PM: %d", s); if (mess.m_type != PM_INIT) panic("unexpected message from PM: %d", mess.m_type); if (NONE == mess.PM_PROC) break; rfp = &fproc[mess.PM_SLOT]; rfp->fp_flags = FP_NOFLAGS; rfp->fp_pid = mess.PM_PID; rfp->fp_endpoint = mess.PM_PROC; rfp->fp_grant = GRANT_INVALID; rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; rfp->fp_realuid = (uid_t) SYS_UID; rfp->fp_effuid = (uid_t) SYS_UID; rfp->fp_realgid = (gid_t) SYS_GID; rfp->fp_effgid = (gid_t) SYS_GID; rfp->fp_umask = ~0; } while (TRUE); /* continue until process NONE */ mess.m_type = OK; /* tell PM that we succeeded */ s = send(PM_PROC_NR, &mess); /* send synchronization message */ /* All process table entries have been set. Continue with initialization. */ fp = &fproc[_ENDPOINT_P(VFS_PROC_NR)];/* During init all communication with * FSes is on behalf of myself */ init_dmap(); /* Initialize device table. */ system_hz = sys_hz(); /* Map all the services in the boot image. */ if ((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK){ panic("sys_safecopyfrom failed: %d", s); } for (i = 0; i < NR_BOOT_PROCS; i++) { if (rprocpub[i].in_use) { if ((s = map_service(&rprocpub[i])) != OK) { panic("VFS: unable to map service: %d", s); } } } /* Subscribe to block and character driver events. */ s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE); if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s); /* Initialize worker threads */ for (i = 0; i < NR_WTHREADS; i++) { worker_init(&workers[i]); } worker_init(&sys_worker); /* exclusive system worker thread */ worker_init(&dl_worker); /* exclusive worker thread to resolve deadlocks */ /* Initialize global locks */ if (mthread_mutex_init(&pm_lock, NULL) != 0) panic("VFS: couldn't initialize pm lock mutex"); if (mthread_mutex_init(&exec_lock, NULL) != 0) panic("VFS: couldn't initialize exec lock"); if (mthread_mutex_init(&bsf_lock, NULL) != 0) panic("VFS: couldn't initialize block special file lock"); /* Initialize event resources for boot procs and locks for all procs */ for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { if (mutex_init(&rfp->fp_lock, NULL) != 0) panic("unable to initialize fproc lock"); #if LOCK_DEBUG rfp->fp_vp_rdlocks = 0; rfp->fp_vmnt_rdlocks = 0; #endif } init_vnodes(); /* init vnodes */ init_vmnts(); /* init vmnt structures */ init_select(); /* init select() structures */ init_filps(); /* Init filp structures */ mount_pfs(); /* mount Pipe File Server */ worker_start(do_init_root); /* mount initial ramdisk as file system root */ yield(); /* force do_init_root to start */ self = NULL; return(OK); }
/*===========================================================================* * get_work * *===========================================================================*/ PRIVATE void get_work() { /* Normally wait for new input. However, if 'reviving' is * nonzero, a suspended process must be awakened. */ int r, found_one, fd_nr; struct filp *f; register struct fproc *rp; while (reviving != 0) { found_one= FALSE; /* Revive a suspended process. */ for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) if (rp->fp_pid != PID_FREE && rp->fp_revived == REVIVING) { int blocked_on = rp->fp_blocked_on; found_one= TRUE; who_p = (int)(rp - fproc); who_e = rp->fp_endpoint; call_nr = rp->fp_block_callnr; m_in.fd = rp->fp_block_fd; m_in.buffer = rp->fp_buffer; m_in.nbytes = rp->fp_nbytes; /*no longer hanging*/ rp->fp_blocked_on = FP_BLOCKED_ON_NONE; rp->fp_revived = NOT_REVIVING; reviving--; /* This should be a pipe I/O, not a device I/O. * If it is, it'll 'leak' grants. */ assert(!GRANT_VALID(rp->fp_grant)); if (blocked_on == FP_BLOCKED_ON_PIPE) { fp= rp; fd_nr= rp->fp_block_fd; f= get_filp(fd_nr); assert(f != NULL); r= rw_pipe((call_nr == READ) ? READING : WRITING, who_e, fd_nr, f, rp->fp_buffer, rp->fp_nbytes); if (r != SUSPEND) reply(who_e, r); continue; } return; } if (!found_one) panic("get_work couldn't revive anyone"); } for(;;) { int r; /* Normal case. No one to revive. */ if ((r=sef_receive(ANY, &m_in)) != OK) panic("fs sef_receive error: %d", r); who_e = m_in.m_source; who_p = _ENDPOINT_P(who_e); /* * negative who_p is never used to access the fproc array. Negative numbers * (kernel tasks) are treated in a special way */ if(who_p >= (int)(sizeof(fproc) / sizeof(struct fproc))) panic("receive process out of range: %d", who_p); if(who_p >= 0 && fproc[who_p].fp_endpoint == NONE) { printf("FS: ignoring request from %d, endpointless slot %d (%d)\n", m_in.m_source, who_p, m_in.m_type); continue; } if(who_p >= 0 && fproc[who_p].fp_endpoint != who_e) { if(fproc[who_p].fp_endpoint == NONE) { printf("slot unknown even\n"); } printf("FS: receive endpoint inconsistent (source %d, who_p %d, stored ep %d, who_e %d).\n", m_in.m_source, who_p, fproc[who_p].fp_endpoint, who_e); #if 0 panic("FS: inconsistent endpoint "); #endif continue; } call_nr = m_in.m_type; return; } }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the virtual file server. */ int s, i; register struct fproc *rfp; struct vmnt *vmp; struct vnode *root_vp; message mess; struct rprocpub rprocpub[NR_BOOT_PROCS]; /* Clear endpoint field */ last_login_fs_e = NONE; mount_m_in.m1_p3 = (char *) NONE; /* Initialize the process table with help of the process manager messages. * Expect one message for each system process with its slot number and pid. * When no more processes follow, the magic process number NONE is sent. * Then, stop and synchronize with the PM. */ do { if (OK != (s=sef_receive(PM_PROC_NR, &mess))) panic("FS couldn't receive from PM: %d", s); if (mess.m_type != PM_INIT) panic("unexpected message from PM: %d", mess.m_type); if (NONE == mess.PM_PROC) break; rfp = &fproc[mess.PM_SLOT]; rfp->fp_pid = mess.PM_PID; rfp->fp_endpoint = mess.PM_PROC; rfp->fp_openfd = 0; rfp->fp_realuid = (uid_t) SYS_UID; rfp->fp_effuid = (uid_t) SYS_UID; rfp->fp_realgid = (gid_t) SYS_GID; rfp->fp_effgid = (gid_t) SYS_GID; rfp->fp_umask = ~0; rfp->fp_grant = GRANT_INVALID; rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; rfp->fp_revived = NOT_REVIVING; rfp->fp_fsizelim.rlim_cur = RLIM_FSIZE_DEFAULT; rfp->fp_fsizelim.rlim_max = RLIM_FSIZE_DEFAULT; rfp->fp_nofilelim.rlim_cur = RLIM_NOFILE_DEFAULT; rfp->fp_nofilelim.rlim_max = RLIM_NOFILE_DEFAULT; } while (TRUE); /* continue until process NONE */ mess.m_type = OK; /* tell PM that we succeeded */ s = send(PM_PROC_NR, &mess); /* send synchronization message */ /* All process table entries have been set. Continue with initialization. */ /* The following initializations are needed to let dev_opcl succeed .*/ fp = (struct fproc *) NULL; who_e = who_p = VFS_PROC_NR; /* Initialize device table. */ build_dmap(); /* Map all the services in the boot image. */ if((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) { panic("sys_safecopyfrom failed: %d", s); } for(i=0;i < NR_BOOT_PROCS;i++) { if(rprocpub[i].in_use) { if((s = map_service(&rprocpub[i])) != OK) { panic("unable to map service: %d", s); } } } init_root(); /* init root device and load super block */ init_select(); /* init select() structures */ vmp = &vmnt[0]; /* Should be the root filesystem */ if (vmp->m_dev == NO_DEV) panic("vfs: no root filesystem"); root_vp= vmp->m_root_node; /* The root device can now be accessed; set process directories. */ for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { FD_ZERO(&(rfp->fp_filp_inuse)); if (rfp->fp_pid != PID_FREE) { dup_vnode(root_vp); rfp->fp_rd = root_vp; dup_vnode(root_vp); rfp->fp_wd = root_vp; } else rfp->fp_endpoint = NONE; } system_hz = sys_hz(); /* Subscribe to driver events for VFS drivers. */ s = ds_subscribe("drv\\.vfs\\..*", DSF_INITIAL | DSF_OVERWRITE); if(s != OK) { panic("vfs: can't subscribe to driver events"); } SANITYCHECK; #if DO_SANITYCHECKS FIXME("VFS: DO_SANITYCHECKS is on"); #endif return(OK); }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(void) { message msg; int result, who_e; /* SEF local startup. */ sef_local_startup(); /* This is VM's main loop. */ while (TRUE) { int r, c; SANITYCHECK(SCL_TOP); if(missing_spares > 0) { pt_cycle(); /* pagetable code wants to be called */ } SANITYCHECK(SCL_DETAIL); if ((r=sef_receive(ANY, &msg)) != OK) vm_panic("sef_receive() error", r); SANITYCHECK(SCL_DETAIL); if(msg.m_type & NOTIFY_MESSAGE) { switch(msg.m_source) { case SYSTEM: /* Kernel wants to have memory ranges * verified, and/or pagefaults handled. */ do_memory(); break; case HARDWARE: do_pagefaults(); break; case PM_PROC_NR: /* PM sends a notify() on shutdown, which * is OK and we ignore. */ break; default: /* No-one else should send us notifies. */ printf("VM: ignoring notify() from %d\n", msg.m_source); break; } continue; } who_e = msg.m_source; c = CALLNUMBER(msg.m_type); result = ENOSYS; /* Out of range or restricted calls return this. */ if(c < 0 || !vm_calls[c].vmc_func) { printf("VM: out of range or missing callnr %d from %d\n", msg.m_type, who_e); } else if (vm_acl_ok(who_e, c) != OK) { printf("VM: unauthorized %s by %d\n", vm_calls[c].vmc_name, who_e); } else { SANITYCHECK(SCL_FUNCTIONS); result = vm_calls[c].vmc_func(&msg); SANITYCHECK(SCL_FUNCTIONS); } /* Send reply message, unless the return code is SUSPEND, * which is a pseudo-result suppressing the reply message. */ if(result != SUSPEND) { SANITYCHECK(SCL_DETAIL); msg.m_type = result; if((r=send(who_e, &msg)) != OK) { printf("VM: couldn't send %d to %d (err %d)\n", msg.m_type, who_e, r); vm_panic("send() error", NO_NUM); } SANITYCHECK(SCL_DETAIL); } SANITYCHECK(SCL_DETAIL); } return(OK); }
PUBLIC int main(int argc, char *argv[]) { message m; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while (TRUE) { int r; int i; 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 PM_PROC_NR: /* PM sends a notify() on shutdown, * checkout if there are still IPC keys, * give warning messages. */ if (!is_sem_nil() || !is_shm_nil()) printf("IPC: exit with un-clean states.\n"); break; 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; } /* dispatch messages */ for (i = 0; i < SIZE(ipc_calls); i++) { if (ipc_calls[i].type == call_type) { int result; result = ipc_calls[i].func(&m); if (ipc_calls[i].reply) break; m.m_type = result; if(verbose && result != OK) printf("IPC: error for %d: %d\n", call_type, result); if ((r = sendnb(who_e, &m)) != OK) printf("IPC send error %d.\n", r); break; } } if (i == SIZE(ipc_calls)) { /* 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_cb_init_fresh * *===========================================================================*/ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info) { /* Initialize the virtual file server. */ int s, i; struct fproc *rfp; message mess; struct rprocpub rprocpub[NR_BOOT_PROCS]; self = NULL; verbose = 0; /* Initialize proc endpoints to NONE */ for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { rfp->fp_endpoint = NONE; rfp->fp_pid = PID_FREE; } /* Initialize the process table with help of the process manager messages. * Expect one message for each system process with its slot number and pid. * When no more processes follow, the magic process number NONE is sent. * Then, stop and synchronize with the PM. */ do { if ((s = sef_receive(PM_PROC_NR, &mess)) != OK) panic("VFS: couldn't receive from PM: %d", s); if (mess.m_type != VFS_PM_INIT) panic("unexpected message from PM: %d", mess.m_type); if (NONE == mess.VFS_PM_ENDPT) break; rfp = &fproc[mess.VFS_PM_SLOT]; rfp->fp_flags = FP_NOFLAGS; rfp->fp_pid = mess.VFS_PM_PID; rfp->fp_endpoint = mess.VFS_PM_ENDPT; rfp->fp_grant = GRANT_INVALID; rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; rfp->fp_realuid = (uid_t) SYS_UID; rfp->fp_effuid = (uid_t) SYS_UID; rfp->fp_realgid = (gid_t) SYS_GID; rfp->fp_effgid = (gid_t) SYS_GID; rfp->fp_umask = ~0; } while (TRUE); /* continue until process NONE */ mess.m_type = OK; /* tell PM that we succeeded */ s = ipc_send(PM_PROC_NR, &mess); /* send synchronization message */ system_hz = sys_hz(); /* Subscribe to block and character driver events. */ s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE); if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s); /* Initialize worker threads */ worker_init(); /* Initialize global locks */ if (mthread_mutex_init(&bsf_lock, NULL) != 0) panic("VFS: couldn't initialize block special file lock"); init_dmap(); /* Initialize device table. */ /* Map all the services in the boot image. */ if ((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, (vir_bytes) rprocpub, sizeof(rprocpub))) != OK){ panic("sys_safecopyfrom failed: %d", s); } for (i = 0; i < NR_BOOT_PROCS; i++) { if (rprocpub[i].in_use) { if ((s = map_service(&rprocpub[i])) != OK) { panic("VFS: unable to map service: %d", s); } } } /* Initialize locks and initial values for all processes. */ for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { if (mutex_init(&rfp->fp_lock, NULL) != 0) panic("unable to initialize fproc lock"); rfp->fp_worker = NULL; #if LOCK_DEBUG rfp->fp_vp_rdlocks = 0; rfp->fp_vmnt_rdlocks = 0; #endif /* Initialize process directories. mount_fs will set them to the * correct values. */ for (i = 0; i < OPEN_MAX; i++) rfp->fp_filp[i] = NULL; rfp->fp_rd = NULL; rfp->fp_wd = NULL; } init_vnodes(); /* init vnodes */ init_vmnts(); /* init vmnt structures */ init_select(); /* init select() structures */ init_filps(); /* Init filp structures */ /* Mount PFS and initial file system root. */ worker_start(fproc_addr(VFS_PROC_NR), do_init_root, &mess /*unused*/, FALSE /*use_spare*/); return(OK); }
PUBLIC int main(int argc, char *argv[]) { message m; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while (TRUE) { int r; int i; 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; } /* dispatch messages */ for (i = 0; i < SIZE(ipc_calls); i++) { /* 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); } if (ipc_calls[i].type == call_type) { int result; result = ipc_calls[i].func(&m); if (ipc_calls[i].reply) break; m.m_type = result; if(verbose && result != OK) printf("IPC: error for %d: %d\n", call_type, result); if ((r = sendnb(who_e, &m)) != OK) printf("IPC send error %d.\n", r); break; } } if (i == SIZE(ipc_calls)) { /* 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; }
/*===========================================================================* * main * *===========================================================================*/ int main(void) { int r; message mess; char key[DS_MAX_KEYLEN]; int type; u32_t num; char string[17]; char buf[1000]; size_t length = 1000; /* SEF local startup. */ sef_local_startup(); /* Subscribe. */ r = ds_subscribe(key_u32, DSF_INITIAL); if(r != OK && r != EEXIST) { printf("SUBSCRIBER: error in ds_subscribe: %d\n", r); return -1; } while(1) { /* Wait for a message. */ r = sef_receive(ANY, &mess); if(r != OK) { printf("SUBSCRIBER: sef_receive failed.\n"); return 1; } /* Only handle notifications from DS. */ if(mess.m_source != DS_PROC_NR) continue; /* Check which one was changed. */ r = ds_check(key, &type, NULL); if(r == ENOENT) { printf("SUBSCRIBER: the key %s was deleted.\n", key); continue; } if(r != OK) { printf("SUBSCRIBER: error in ds_check.\n"); continue; } /* Retrieve the entry. */ printf("SUBSCRIBER: key: %s, ", key); switch(type) { case DSF_TYPE_U32: r = ds_retrieve_u32(key, &num); if(r != OK) printf("error in ds_retrieve_u32.\n"); printf("U32: %d\n", num); break; case DSF_TYPE_STR: r = ds_retrieve_str(key, string, sizeof(string)-1); if(r != OK) printf("error in ds_retrieve_str.\n"); printf("STR: %s\n", string); break; case DSF_TYPE_MEM: r = ds_retrieve_mem(key, buf, &length); if(r != OK) printf("error in ds_retrieve_mem.\n"); break; case DSF_TYPE_MAP: break; default: printf("error in type! %d\n", type); } } return 0; }