static void setExceptionThread(void) { kern_return_t r; // char *nullAddr = NULL; bailOut = FALSE; /* save the old exception port for this task */ r = task_get_exception_port(task_self(), &(ports.old_exc_port)); if (r != KERN_SUCCESS) { mach_error("task_get_exception_port",r); exit(1); } if (!ports.exc_port) { /* create a new exception port for this task */ r = port_allocate(task_self(), &(ports.exc_port)); if (r != KERN_SUCCESS) { mach_error("port_allocate",r); exit(1); } /* Fork the thread that listens to the exception port. */ cthread_detach(cthread_fork((cthread_fn_t)exc_thread,(any_t)&ports)); ports.clear_port = thread_reply(); } /* install the new exception port for this task */ r = task_set_exception_port(task_self(), (ports.exc_port)); if (r != KERN_SUCCESS) { mach_error("task_set_exception_port",r); exit(1); } }
int main (int argc, char **argv) { int nthreads; int fail; if (argc > 2) { fprintf (stderr, "%s [num-threads]\n", argv[0]); exit (1); } if (argc == 1) nthreads = 4; else nthreads = atoi (argv[1]); if (!nthreads) nthreads = 4; authserver = getauth (); maptime_map (0, 0, &mapped_time); main_address.sin_family = AF_INET; main_address.sin_port = htons (NFS_PORT); main_address.sin_addr.s_addr = INADDR_ANY; pmap_address.sin_family = AF_INET; pmap_address.sin_port = htons (PMAPPORT); pmap_address.sin_addr.s_addr = INADDR_ANY; main_udp_socket = socket (PF_INET, SOCK_DGRAM, 0); pmap_udp_socket = socket (PF_INET, SOCK_DGRAM, 0); fail = bind (main_udp_socket, (struct sockaddr *)&main_address, sizeof (struct sockaddr_in)); if (fail) error (1, errno, "Binding NFS socket"); fail = bind (pmap_udp_socket, (struct sockaddr *)&pmap_address, sizeof (struct sockaddr_in)); if (fail) error (1, errno, "Binding PMAP socket"); init_filesystems (); cthread_detach (cthread_fork ((cthread_fn_t) server_loop, (any_t)(intptr_t) pmap_udp_socket)); while (nthreads--) cthread_detach (cthread_fork ((cthread_fn_t) server_loop, (any_t)(intptr_t) main_udp_socket)); for (;;) { sleep (1); scan_fhs (); scan_creds (); scan_replies (); } }
static error_t hurdio_init (void) { condition_init (&hurdio_writer_condition); condition_init (&hurdio_assert_dtr_condition); cthread_detach (cthread_fork (hurdio_reader_loop, 0)); cthread_detach (cthread_fork (hurdio_writer_loop, 0)); return 0; }
void OSThread::Start() { #ifdef __Win32__ unsigned int theId = 0; // We don't care about the identifier fThreadID = (HANDLE)_beginthreadex(NULL, // Inherit security 0, // Inherit stack size _Entry, // Entry function (void*)this, // Entry arg 0, // Begin executing immediately &theId); Assert(fThreadID != NULL); #elif __PTHREADS__ pthread_attr_t* theAttrP; #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING //theAttrP = &sThreadAttr; theAttrP = 0; #else theAttrP = NULL; #endif int err = pthread_create((pthread_t*)&fThreadID, theAttrP, _Entry, (void*)this); Assert(err == 0); #else fThreadID = (UInt32)cthread_fork((cthread_fn_t)_Entry, (any_t)this); #endif }
default_pager_thread_t * start_default_pager_thread( int id, boolean_t internal) { default_pager_thread_t *dpt; kern_return_t kr; static char here[] = "start_default_pager_thread"; dpt = (default_pager_thread_t *)kalloc(sizeof (default_pager_thread_t)); if (dpt == 0) Panic("alloc pager thread"); dpt->dpt_internal = internal; dpt->dpt_id = id; dpt->dpt_initialized_p = FALSE; kr = vm_allocate(default_pager_self, &dpt->dpt_buffer, vm_page_size, TRUE); if (kr != KERN_SUCCESS) Panic("alloc thread buffer"); wire_memory(dpt->dpt_buffer, vm_page_size, VM_PROT_READ | VM_PROT_WRITE); dpt->dpt_thread = cthread_fork((cthread_fn_t) default_pager_thread, (void *) dpt); return dpt; }
static error_t pc_mouse_start (void *handle) { error_t err; char device_name[9]; int devnum = majordev << 3 | minordev; device_t device_master; sprintf (device_name, "mouse%d", devnum); err = get_privileged_ports (0, &device_master); if (err) return err; err = device_open (device_master, D_READ, device_name, &mousedev); mach_port_deallocate (mach_task_self (), device_master); if (err) return ENODEV; err = driver_add_input (&pc_mouse_ops, NULL); if (err) { device_close (mousedev); mach_port_deallocate (mach_task_self (), mousedev); return err; } cthread_detach (cthread_fork (input_loop, NULL)); if (repeater_node) setrepeater (repeater_node); return 0; }
int ldap_pvt_thread_create( ldap_pvt_thread_t * thread, int detach, void *(*start_routine)( void *), void *arg) { *thread = cthread_fork( (cthread_fn_t) start_routine, arg); return ( *thread == NULL ? -1 : 0 ); }
void root_update_init() { mutex_init (&update_lock); rwlock_init (&update_rwlock); condition_init (&update_wakeup); cthread_detach (cthread_fork ( (cthread_fn_t)_root_update_thread, 0)); }
kern_return_t server_thread_start( void *(*func)(void *), void *arg) { cthread_t child; child = cthread_fork(func, arg); if (child == CTHREAD_NULL) { panic("server_thread_start: cthread_fork failed"); return KERN_FAILURE; } /* let the new thread start */ osfmach3_yield(); return KERN_SUCCESS; }
void diskfs_start_disk_pager (struct user_pager_info *upi, struct port_bucket *pager_bucket, int may_cache, size_t size, void **image) { error_t err; mach_port_t disk_pager_port; /* Make a thread to service paging requests. */ cthread_detach (cthread_fork ((cthread_fn_t) service_paging_requests, (any_t)pager_bucket)); /* Create the pager. */ diskfs_disk_pager = pager_create (upi, pager_bucket, may_cache, MEMORY_OBJECT_COPY_NONE); assert (diskfs_disk_pager); /* Get a port to the disk pager. */ disk_pager_port = pager_get_port (diskfs_disk_pager); mach_port_insert_right (mach_task_self (), disk_pager_port, disk_pager_port, MACH_MSG_TYPE_MAKE_SEND); /* Now map the disk image. */ err = vm_map (mach_task_self (), (vm_address_t *)image, size, 0, 1, disk_pager_port, 0, 0, VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_NONE); if (err) error (2, err, "cannot vm_map whole disk"); /* Set up the signal preemptor to catch faults on the disk image. */ preemptor.first = (vm_address_t) *image; preemptor.last = ((vm_address_t) *image + size); hurd_preempt_signals (&preemptor); /* We have the mapping; we no longer need the send right. */ mach_port_deallocate (mach_task_self (), disk_pager_port); }
/* Establish a thread to sync the filesystem every INTERVAL seconds, or never, if INTERVAL is zero. If an error occurs creating the thread, it is returned, otherwise 0. Subsequent calls will create a new thread and (eventually) get rid of the old one; the old thread won't do any more syncs, regardless. */ error_t diskfs_set_sync_interval (int interval) { error_t err = 0; if (! pi) { err = ports_create_port (diskfs_control_class, diskfs_port_bucket, sizeof (struct port_info), &pi); if (err) return err; } err = ports_inhibit_port_rpcs (pi); if (err) return err; /* Here we just set the new thread; any existing thread will notice when it wakes up and go away silently. */ if (interval == 0) periodic_sync_thread = 0; else { periodic_sync_thread = cthread_fork ((cthread_fn_t)periodic_sync, (any_t)(intptr_t)interval); if (periodic_sync_thread) cthread_detach (periodic_sync_thread); else err = ENOMEM; } if (!err) diskfs_sync_interval = interval; ports_resume_port_rpcs (pi); return err; }
/* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't block in any fashion. */ void send_signal (mach_port_t msgport, int signal, mach_port_t refport) { error_t err; /* This message buffer might be modified by mach_msg in some error cases, so we cannot safely use a shared static buffer. */ struct msg_sig_post_request message = { { /* Message header: */ (MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */ sizeof message, /* msgh_size */ msgport, /* msgh_remote_port */ MACH_PORT_NULL, /* msgh_local_port */ 0, /* msgh_seqno */ RPCID_SIG_POST, /* msgh_id */ }, { /* Type descriptor for signo */ MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ 32, /* msgt_size */ 1, /* msgt_number */ 1, /* msgt_inline */ 0, /* msgt_longform */ 0, /* msgt_deallocate */ 0, /* msgt_unused */ }, /* Signal number */ signal, /* Type descriptor for sigcode */ { MACH_MSG_TYPE_INTEGER_32, /* msgt_name */ 32, /* msgt_size */ 1, /* msgt_number */ 1, /* msgt_inline */ 0, /* msgt_longform */ 0, /* msgt_deallocate */ 0, /* msgt_unused */ }, /* Sigcode */ 0, { /* Type descriptor for refport */ MACH_MSG_TYPE_COPY_SEND, /* msgt_name */ 32, /* msgt_size */ 1, /* msgt_number */ 1, /* msgt_inline */ 0, /* msgt_longform */ 0, /* msgt_deallocate */ 0, /* msgt_unused */ }, refport }; err = mach_msg ((mach_msg_header_t *)&message, MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL); switch (err) { case MACH_SEND_TIMED_OUT: /* The send could not complete immediately, and we do not want to block. We'll fork off another thread to do the blocking send. The message buffer was modified by a pseudo-receive operation, so we need to copy its modified contents into a malloc'd buffer. */ { struct msg_sig_post_request *copy = malloc (sizeof *copy); if (copy) { memcpy (copy, &message, sizeof message); cthread_detach (cthread_fork (blocking_message_send, copy)); } break; } /* These are the other codes that mean a pseudo-receive modified the message buffer and we might need to clean up the send rights. None of them should be possible in our usage. */ case MACH_SEND_INTERRUPTED: case MACH_SEND_INVALID_NOTIFY: case MACH_SEND_NO_NOTIFY: case MACH_SEND_NOTIFY_IN_PROGRESS: assert_perror (err); break; default: /* Other errors are safe to ignore. */ break; } }