b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * CDDL HEADER START
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * The contents of this file are subject to the terms of the
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Common Development and Distribution License (the "License").
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * You may not use this file except in compliance with the License.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * or http://www.opensolaris.org/os/licensing.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * See the License for the specific language governing permissions
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * and limitations under the License.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * When distributing Covered Code, include this CDDL HEADER in each
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * If applicable, add the following below this CDDL HEADER, with the
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner]
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * CDDL HEADER END
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/param.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/types.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/tzfile.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/atomic.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/kidmap.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/time.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/spl.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/random.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <smbsrv/smb_kproto.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <smbsrv/smb_fsops.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <smbsrv/smbinfo.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <smbsrv/smb_xdr.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <smbsrv/smb_vops.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <smbsrv/smb_idmap.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/sid.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/priv_names.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#ifdef _FAKE_KERNEL
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#define THR_TO_DID(t) ((kt_did_t)(uintptr_t)t)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#else
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#define THR_TO_DID(t) (t->t_did)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#endif
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossstatic boolean_t smb_thread_continue_timedwait_locked(smb_thread_t *, int);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_entry_point
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Common entry point for all the threads created through smb_thread_start.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * The state of the thread is set to "running" at the beginning and moved to
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * "exiting" just before calling thread_exit(). The condition variable is
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * also signaled.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossstatic void
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_entry_point(
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_state == SMB_THREAD_STATE_STARTING);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (!thread->sth_kill) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_state = SMB_THREAD_STATE_RUNNING;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_signal(&thread->sth_cv);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross /* Run the real thread entry point. */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_ep(thread, thread->sth_ep_arg);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross /*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * It's tempting to clear sth_did here too, but don't.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * That's needed in thread_join().
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_th = NULL;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_state = SMB_THREAD_STATE_EXITING;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_broadcast(&thread->sth_cv);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross zthread_exit();
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_init
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossvoid
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_init(
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross smb_thread_t *thread,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross char *name,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross smb_thread_ep_t ep,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross void *ep_arg,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross pri_t pri)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic != SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross bzero(thread, sizeof (*thread));
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross (void) strlcpy(thread->sth_name, name, sizeof (thread->sth_name));
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_ep = ep;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_ep_arg = ep_arg;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_state = SMB_THREAD_STATE_EXITED;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_pri = pri;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_init(&thread->sth_mtx, NULL, MUTEX_DEFAULT, NULL);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_init(&thread->sth_cv, NULL, CV_DEFAULT, NULL);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_magic = SMB_THREAD_MAGIC;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_destroy
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossvoid
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_destroy(
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_state == SMB_THREAD_STATE_EXITED);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_magic = 0;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_destroy(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_destroy(&thread->sth_cv);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_start
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * This function starts a thread with the parameters provided. It waits until
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * the state of the thread has been moved to running.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*ARGSUSED*/
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossint
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_start(
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross int rc = 0;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross kthread_t *tmpthread;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross switch (thread->sth_state) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross case SMB_THREAD_STATE_EXITED:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_state = SMB_THREAD_STATE_STARTING;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross tmpthread = zthread_create(NULL, 0, smb_thread_entry_point,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread, 0, thread->sth_pri);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(tmpthread != NULL);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_th = tmpthread;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_did = THR_TO_DID(tmpthread);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross while (thread->sth_state == SMB_THREAD_STATE_STARTING)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_wait(&thread->sth_cv, &thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (thread->sth_state != SMB_THREAD_STATE_RUNNING)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross rc = -1;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross default:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(0);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross rc = -1;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross return (rc);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_stop
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * This function signals a thread to kill itself and waits until the "exiting"
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * state has been reached.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossvoid
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_stop(smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross switch (thread->sth_state) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross case SMB_THREAD_STATE_RUNNING:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross case SMB_THREAD_STATE_STARTING:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (!thread->sth_kill) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_kill = B_TRUE;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_broadcast(&thread->sth_cv);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross while (thread->sth_state != SMB_THREAD_STATE_EXITING)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_wait(&thread->sth_cv, &thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread_join(thread->sth_did);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_state = SMB_THREAD_STATE_EXITED;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_did = 0;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_kill = B_FALSE;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_broadcast(&thread->sth_cv);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross /* FALLTHROUGH */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross case SMB_THREAD_STATE_EXITING:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (thread->sth_kill) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross while (thread->sth_state != SMB_THREAD_STATE_EXITED)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_wait(&thread->sth_cv, &thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross } else {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_state = SMB_THREAD_STATE_EXITED;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross thread->sth_did = 0;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross case SMB_THREAD_STATE_EXITED:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross default:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(0);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_signal
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * This function signals a thread.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossvoid
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_signal(smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross switch (thread->sth_state) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross case SMB_THREAD_STATE_RUNNING:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_signal(&thread->sth_cv);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross default:
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross break;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossboolean_t
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_continue(smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross boolean_t result;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross result = smb_thread_continue_timedwait_locked(thread, 0);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross return (result);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossboolean_t
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_continue_nowait(smb_thread_t *thread)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross boolean_t result;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross /*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Setting ticks=-1 requests a non-blocking check. We will
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * still block if the thread is in "suspend" state.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross result = smb_thread_continue_timedwait_locked(thread, -1);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross return (result);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossboolean_t
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_continue_timedwait(smb_thread_t *thread, int seconds)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross boolean_t result;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_enter(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross result = smb_thread_continue_timedwait_locked(thread,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross SEC_TO_TICK(seconds));
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross mutex_exit(&thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross return (result);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross/*
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * smb_thread_continue_timedwait_locked
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Internal only. Ticks==-1 means don't block, Ticks == 0 means wait
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * indefinitely
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossstatic boolean_t
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rosssmb_thread_continue_timedwait_locked(smb_thread_t *thread, int ticks)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross boolean_t result;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross /* -1 means don't block */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (ticks != -1 && !thread->sth_kill) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (ticks == 0) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross cv_wait(&thread->sth_cv, &thread->sth_mtx);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross } else {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross (void) cv_reltimedwait(&thread->sth_cv,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross &thread->sth_mtx, (clock_t)ticks, TR_CLOCK_TICK);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross result = (thread->sth_kill == 0);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross return (result);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross}