process_thread.c
来自「samba最新软件」· C语言 代码 · 共 573 行 · 第 1/2 页
C
573 行
*****************************************************************/ /* rwlock init function for thread model*/static int thread_rwlock_init(smb_rwlock_t *rwlock, const char *name){ pthread_rwlock_t m = PTHREAD_RWLOCK_INITIALIZER; rwlock->rwlock = memdup(&m, sizeof(m)); if (! rwlock->rwlock) { errno = ENOMEM; return -1; } return pthread_rwlock_init((pthread_rwlock_t *)rwlock->rwlock, NULL);}/* rwlock destroy function for thread model*/static int thread_rwlock_destroy(smb_rwlock_t *rwlock, const char *name){ return pthread_rwlock_destroy((pthread_rwlock_t *)rwlock->rwlock);}/* rwlock lock for read function for thread model*/static int thread_rwlock_lock_read(smb_rwlock_t *rwlockP, const char *name){ pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock; int rc; double t; struct timeval tp1; /* Test below is ONLY for debugging */ if ((rc = pthread_rwlock_tryrdlock(rwlock))) { if (rc == EBUSY) { mutex_start_timer(&tp1); printf("rwlock lock_read: thread %d, lock %s not available\n", (uint32_t)pthread_self(), name); print_suspicious_usage("rwlock_lock_read", name); pthread_rwlock_rdlock(rwlock); t = mutex_end_timer(tp1); printf("rwlock lock_read: thread %d, lock %s now available, waited %g seconds\n", (uint32_t)pthread_self(), name, t); return 0; } printf("rwlock lock_read: thread %d, lock %s failed rc=%d\n", (uint32_t)pthread_self(), name, rc); SMB_ASSERT(errno == 0); /* force error */ } return 0;}/* rwlock lock for write function for thread model*/static int thread_rwlock_lock_write(smb_rwlock_t *rwlockP, const char *name){ pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock; int rc; double t; struct timeval tp1; /* Test below is ONLY for debugging */ if ((rc = pthread_rwlock_trywrlock(rwlock))) { if (rc == EBUSY) { mutex_start_timer(&tp1); printf("rwlock lock_write: thread %d, lock %s not available\n", (uint32_t)pthread_self(), name); print_suspicious_usage("rwlock_lock_write", name); pthread_rwlock_wrlock(rwlock); t = mutex_end_timer(tp1); printf("rwlock lock_write: thread %d, lock %s now available, waited %g seconds\n", (uint32_t)pthread_self(), name, t); return 0; } printf("rwlock lock_write: thread %d, lock %s failed rc=%d\n", (uint32_t)pthread_self(), name, rc); SMB_ASSERT(errno == 0); /* force error */ } return 0;}/* rwlock unlock for thread model*/static int thread_rwlock_unlock(smb_rwlock_t *rwlock, const char *name){ return pthread_rwlock_unlock((pthread_rwlock_t *)rwlock->rwlock);}/***************************************************************** Log suspicious usage (primarily for possible thread-unsafe behavior).*****************************************************************/ static void thread_log_suspicious_usage(const char* from, const char* info){ DEBUG(1,("log_suspicious_usage: from %s info='%s'\n", from, info));#ifdef HAVE_BACKTRACE { void *addresses[10]; int num_addresses = backtrace(addresses, 8); char **bt_symbols = backtrace_symbols(addresses, num_addresses); int i; if (bt_symbols) { for (i=0; i<num_addresses; i++) { DEBUG(1,("log_suspicious_usage: %s%s\n", DEBUGTAB(1), bt_symbols[i])); } free(bt_symbols); } }#endif}/***************************************************************** Log suspicious usage to stdout (primarily for possible thread-unsafe behavior. Used in mutex code where DEBUG calls would cause recursion.*****************************************************************/ static void thread_print_suspicious_usage(const char* from, const char* info){ printf("log_suspicious_usage: from %s info='%s'\n", from, info);#ifdef HAVE_BACKTRACE { void *addresses[10]; int num_addresses = backtrace(addresses, 8); char **bt_symbols = backtrace_symbols(addresses, num_addresses); int i; if (bt_symbols) { for (i=0; i<num_addresses; i++) { printf("log_suspicious_usage: %s%s\n", DEBUGTAB(1), bt_symbols[i]); } free(bt_symbols); } }#endif}static uint32_t thread_get_task_id(void){ return (uint32_t)pthread_self();}static void thread_log_task_id(int fd){ char *s= NULL; asprintf(&s, "thread[%u][%s]:\n", (uint32_t)pthread_self(), (const char *)pthread_getspecific(title_key)); if (!s) return; write(fd, s, strlen(s)); free(s);}/****************************************************************************catch serious errors****************************************************************************/static void thread_sig_fault(int sig){ DEBUG(0,("===============================================================\n")); DEBUG(0,("TERMINAL ERROR: Recursive signal %d in thread [%u][%s] (%s)\n", sig,(uint32_t)pthread_self(), (const char *)pthread_getspecific(title_key), SAMBA_VERSION_STRING)); DEBUG(0,("===============================================================\n")); exit(1); /* kill the whole server for now */}/*******************************************************************setup our recursive fault handlers********************************************************************/static void thread_fault_setup(void){#ifdef SIGSEGV CatchSignal(SIGSEGV,SIGNAL_CAST thread_sig_fault);#endif#ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST thread_sig_fault);#endif#ifdef SIGABRT CatchSignal(SIGABRT,SIGNAL_CAST thread_sig_fault);#endif}/*******************************************************************report a fault in a thread********************************************************************/static void thread_fault_handler(int sig){ static int counter; /* try to catch recursive faults */ thread_fault_setup(); counter++; /* count number of faults that have occurred */ DEBUG(0,("===============================================================\n")); DEBUG(0,("INTERNAL ERROR: Signal %d in thread [%u] [%s] (%s)\n", sig,(uint32_t)pthread_self(), (const char *)pthread_getspecific(title_key), SAMBA_VERSION_STRING)); DEBUG(0,("Please read the file BUGS.txt in the distribution\n")); DEBUG(0,("===============================================================\n"));#ifdef HAVE_BACKTRACE { void *addresses[10]; int num_addresses = backtrace(addresses, 8); char **bt_symbols = backtrace_symbols(addresses, num_addresses); int i; if (bt_symbols) { for (i=0; i<num_addresses; i++) { DEBUG(1,("fault_report: %s%s\n", DEBUGTAB(1), bt_symbols[i])); } free(bt_symbols); } }#endif pthread_exit(NULL); /* terminate failing thread only */}/* called when the process model is selected*/static void thread_model_init(struct event_context *event_context){ struct mutex_ops m_ops; struct debug_ops d_ops; ZERO_STRUCT(m_ops); ZERO_STRUCT(d_ops); pthread_key_create(&title_key, NULL); pthread_setspecific(title_key, talloc_strdup(event_context, "")); /* register mutex/rwlock handlers */ m_ops.mutex_init = thread_mutex_init; m_ops.mutex_lock = thread_mutex_lock; m_ops.mutex_unlock = thread_mutex_unlock; m_ops.mutex_destroy = thread_mutex_destroy; m_ops.rwlock_init = thread_rwlock_init; m_ops.rwlock_lock_write = thread_rwlock_lock_write; m_ops.rwlock_lock_read = thread_rwlock_lock_read; m_ops.rwlock_unlock = thread_rwlock_unlock; m_ops.rwlock_destroy = thread_rwlock_destroy; register_mutex_handlers("thread", &m_ops); register_fault_handler("thread", thread_fault_handler); d_ops.log_suspicious_usage = thread_log_suspicious_usage; d_ops.print_suspicious_usage = thread_print_suspicious_usage; d_ops.get_task_id = thread_get_task_id; d_ops.log_task_id = thread_log_task_id; register_debug_handlers("thread", &d_ops);}static const struct model_ops thread_ops = { .name = "thread", .model_init = thread_model_init, .accept_connection = thread_accept_connection, .new_task = thread_new_task, .terminate = thread_terminate, .set_title = thread_set_title,};/* initialise the thread process model, registering ourselves with the model subsystem */NTSTATUS process_model_thread_init(void){ NTSTATUS ret; /* register ourselves with the PROCESS_MODEL subsystem. */ ret = register_process_model(&thread_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register process_model 'thread'!\n")); return ret; } return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?