svn commit: r246444 - in user/attilio/vmc-playground/sys: dev/sound/pcm dev/sound/usb fs/nfs kern nfsclient sys
Attilio Rao
attilio at FreeBSD.org
Wed Feb 6 23:42:07 UTC 2013
Author: attilio
Date: Wed Feb 6 23:42:04 2013
New Revision: 246444
URL: http://svnweb.freebsd.org/changeset/base/246444
Log:
Merge from vmcontention
Modified:
user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.c
user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.h
user/attilio/vmc-playground/sys/dev/sound/usb/uaudio.c
user/attilio/vmc-playground/sys/fs/nfs/nfs_commonkrpc.c
user/attilio/vmc-playground/sys/kern/kern_sig.c
user/attilio/vmc-playground/sys/kern/subr_sleepqueue.c
user/attilio/vmc-playground/sys/kern/vfs_acl.c
user/attilio/vmc-playground/sys/nfsclient/nfs_krpc.c
user/attilio/vmc-playground/sys/sys/signalvar.h
Directory Properties:
user/attilio/vmc-playground/ (props changed)
user/attilio/vmc-playground/sys/ (props changed)
Modified: user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.c
==============================================================================
--- user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -1492,3 +1492,30 @@ mixer_get_lock(struct snd_mixer *m)
}
return (m->lock);
}
+
+int
+mix_get_locked(struct snd_mixer *m, u_int dev, int *pleft, int *pright)
+{
+ int level;
+
+ level = mixer_get(m, dev);
+ if (level < 0) {
+ *pright = *pleft = -1;
+ return (-1);
+ }
+
+ *pleft = level & 0xFF;
+ *pright = (level >> 8) & 0xFF;
+
+ return (0);
+}
+
+int
+mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right)
+{
+ int level;
+
+ level = (left & 0xFF) | ((right & 0xFF) << 8);
+
+ return (mixer_set(m, dev, level));
+}
Modified: user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.h
==============================================================================
--- user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.h Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/dev/sound/pcm/mixer.h Wed Feb 6 23:42:04 2013 (r246444)
@@ -45,6 +45,8 @@ void mixer_hwvol_step(device_t dev, int
int mixer_busy(struct snd_mixer *m);
+int mix_get_locked(struct snd_mixer *m, u_int dev, int *pleft, int *pright);
+int mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right);
int mix_set(struct snd_mixer *m, u_int dev, u_int left, u_int right);
int mix_get(struct snd_mixer *m, u_int dev);
int mix_setrecsrc(struct snd_mixer *m, u_int32_t src);
Modified: user/attilio/vmc-playground/sys/dev/sound/usb/uaudio.c
==============================================================================
--- user/attilio/vmc-playground/sys/dev/sound/usb/uaudio.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/dev/sound/usb/uaudio.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbhid.h>
#include <dev/usb/usb_request.h>
#define USB_DEBUG_VAR uaudio_debug
@@ -277,16 +278,37 @@ struct uaudio_search_result {
uint8_t is_input;
};
+enum {
+ UAUDIO_HID_RX_TRANSFER,
+ UAUDIO_HID_N_TRANSFER,
+};
+
+struct uaudio_hid {
+ struct usb_xfer *xfer[UAUDIO_HID_N_TRANSFER];
+ struct hid_location volume_up_loc;
+ struct hid_location volume_down_loc;
+ uint32_t flags;
+#define UAUDIO_HID_VALID 0x0001
+#define UAUDIO_HID_HAS_ID 0x0002
+#define UAUDIO_HID_HAS_VOLUME_UP 0x0004
+#define UAUDIO_HID_HAS_VOLUME_DOWN 0x0008
+ uint8_t iface_index;
+ uint8_t volume_up_id;
+ uint8_t volume_down_id;
+};
+
struct uaudio_softc {
struct sbuf sc_sndstat;
struct sndcard_func sc_sndcard_func;
struct uaudio_chan sc_rec_chan;
struct uaudio_chan sc_play_chan;
struct umidi_chan sc_midi_chan;
+ struct uaudio_hid sc_hid;
struct uaudio_search_result sc_mixer_clocks;
struct uaudio_mixer_node sc_mixer_node;
struct mtx *sc_mixer_lock;
+ struct snd_mixer *sc_mixer_dev;
struct usb_device *sc_udev;
struct usb_xfer *sc_mixer_xfer[1];
struct uaudio_mixer_node *sc_mixer_root;
@@ -407,6 +429,7 @@ static usb_callback_t uaudio_chan_record
static usb_callback_t uaudio_mixer_write_cfg_callback;
static usb_callback_t umidi_bulk_read_callback;
static usb_callback_t umidi_bulk_write_callback;
+static usb_callback_t uaudio_hid_rx_callback;
/* ==== USB mixer ==== */
@@ -500,6 +523,9 @@ static void umidi_close(struct usb_fifo
static void umidi_init(device_t dev);
static int umidi_probe(device_t dev);
static int umidi_detach(device_t dev);
+static int uaudio_hid_probe(struct uaudio_softc *sc,
+ struct usb_attach_arg *uaa);
+static void uaudio_hid_detach(struct uaudio_softc *sc);
#ifdef USB_DEBUG
static void uaudio_chan_dump_ep_desc(
@@ -624,6 +650,18 @@ static const struct usb_config
},
};
+static const struct usb_config
+ uaudio_hid_config[UAUDIO_HID_N_TRANSFER] = {
+ [UAUDIO_HID_RX_TRANSFER] = {
+ .type = UE_INTERRUPT,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .bufsize = 0, /* use wMaxPacketSize */
+ .flags = {.short_xfer_ok = 1,},
+ .callback = &uaudio_hid_rx_callback,
+ },
+};
+
static devclass_t uaudio_devclass;
static device_method_t uaudio_methods[] = {
@@ -896,7 +934,7 @@ uaudio_attach(device_t dev)
}
device_printf(dev, "MIDI sequencer.\n");
} else {
- device_printf(dev, "No midi sequencer.\n");
+ device_printf(dev, "No MIDI sequencer.\n");
}
DPRINTF("doing child attach\n");
@@ -926,6 +964,12 @@ uaudio_attach(device_t dev)
goto detach;
}
+ if (uaudio_hid_probe(sc, uaa) == 0) {
+ device_printf(dev, "HID volume keys found.\n");
+ } else {
+ device_printf(dev, "No HID volume keys found.\n");
+ }
+
/* reload all mixer settings */
uaudio_mixer_reload_all(sc);
@@ -1034,6 +1078,8 @@ uaudio_detach(device_t dev)
if (sc->sc_rec_chan.valid)
usbd_transfer_unsetup(sc->sc_rec_chan.xfer, UAUDIO_NCHANBUFS + 1);
+ uaudio_hid_detach(sc);
+
if (bus_generic_detach(dev) != 0) {
DPRINTF("detach failed!\n");
}
@@ -1213,6 +1259,18 @@ uaudio_chan_fill_info_sub(struct uaudio_
alt_index++;
}
+ if ((!(sc->sc_hid.flags & UAUDIO_HID_VALID)) &&
+ (id->bInterfaceClass == UICLASS_HID) &&
+ (id->bInterfaceSubClass == 0) &&
+ (id->bInterfaceProtocol == 0) &&
+ (alt_index == 0) &&
+ usbd_get_iface(udev, curidx) != NULL) {
+ DPRINTF("Found HID interface at %d\n",
+ curidx);
+ sc->sc_hid.flags |= UAUDIO_HID_VALID;
+ sc->sc_hid.iface_index = curidx;
+ }
+
uma_if_class =
((id->bInterfaceClass == UICLASS_AUDIO) ||
((id->bInterfaceClass == UICLASS_VENDOR) &&
@@ -2490,6 +2548,9 @@ uaudio_mixer_reload_all(struct uaudio_so
pmc->update[chan / 8] |= (1 << (chan % 8));
}
usbd_transfer_start(sc->sc_mixer_xfer[0]);
+
+ /* start HID volume keys, if any */
+ usbd_transfer_start(sc->sc_hid.xfer[0]);
mtx_unlock(sc->sc_mixer_lock);
}
@@ -4818,6 +4879,7 @@ uaudio_mixer_init_sub(struct uaudio_soft
DPRINTF("\n");
sc->sc_mixer_lock = mixer_get_lock(m);
+ sc->sc_mixer_dev = m;
if (usbd_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index,
sc->sc_mixer_xfer, uaudio_mixer_config, 1, sc,
@@ -5452,6 +5514,162 @@ umidi_detach(device_t dev)
return (0);
}
+static void
+uaudio_hid_rx_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ struct uaudio_softc *sc = usbd_xfer_softc(xfer);
+ const uint8_t *buffer = usbd_xfer_get_frame_buffer(xfer, 0);
+ struct snd_mixer *m;
+ int v;
+ int v_l;
+ int v_r;
+ uint8_t id;
+ int actlen;
+
+ usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ DPRINTF("actlen=%d\n", actlen);
+
+ if (actlen != 0 &&
+ (sc->sc_hid.flags & UAUDIO_HID_HAS_ID)) {
+ id = *buffer;
+ buffer++;
+ actlen--;
+ } else {
+ id = 0;
+ }
+
+ m = sc->sc_mixer_dev;
+
+ if ((sc->sc_hid.flags & UAUDIO_HID_HAS_VOLUME_UP) &&
+ (sc->sc_hid.volume_up_id == id) &&
+ hid_get_data(buffer, actlen,
+ &sc->sc_hid.volume_up_loc)) {
+
+ DPRINTF("Volume Up\n");
+
+ v = mix_get_locked(m, SOUND_MIXER_PCM, &v_l, &v_r);
+ if (v == 0) {
+ v = ((v_l + v_r) / 2) + 5;
+ if (v > 100)
+ v = 100;
+ mix_set_locked(m, SOUND_MIXER_PCM, v, v);
+ }
+ }
+
+ if ((sc->sc_hid.flags & UAUDIO_HID_HAS_VOLUME_DOWN) &&
+ (sc->sc_hid.volume_down_id == id) &&
+ hid_get_data(buffer, actlen,
+ &sc->sc_hid.volume_down_loc)) {
+
+ DPRINTF("Volume Down\n");
+
+ v = mix_get_locked(m, SOUND_MIXER_PCM, &v_l, &v_r);
+ if (v == 0) {
+ v = ((v_l + v_r) / 2) - 5;
+ if (v < 0)
+ v = 0;
+ mix_set_locked(m, SOUND_MIXER_PCM, v, v);
+ }
+ }
+
+ case USB_ST_SETUP:
+tr_setup:
+ /* check if we can put more data into the FIFO */
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+ usbd_transfer_submit(xfer);
+ break;
+
+ default: /* Error */
+ if (error != USB_ERR_CANCELLED) {
+ /* try clear stall first */
+ usbd_xfer_set_stall(xfer);
+ goto tr_setup;
+ }
+ break;
+ }
+}
+
+static int
+uaudio_hid_probe(struct uaudio_softc *sc,
+ struct usb_attach_arg *uaa)
+{
+ void *d_ptr;
+ uint32_t flags;
+ uint16_t d_len;
+ uint8_t id;
+ int error;
+
+ if (!(sc->sc_hid.flags & UAUDIO_HID_VALID))
+ return (-1);
+
+ if (sc->sc_mixer_lock == NULL)
+ return (-1);
+
+ /* Get HID descriptor */
+ error = usbd_req_get_hid_desc(uaa->device, NULL, &d_ptr,
+ &d_len, M_TEMP, sc->sc_hid.iface_index);
+
+ if (error) {
+ DPRINTF("error reading report description\n");
+ return (-1);
+ }
+
+ /* check if there is an ID byte */
+ hid_report_size(d_ptr, d_len, hid_input, &id);
+
+ if (id != 0)
+ sc->sc_hid.flags |= UAUDIO_HID_HAS_ID;
+
+ if (hid_locate(d_ptr, d_len,
+ HID_USAGE2(HUP_CONSUMER, 0xE9 /* Volume Increment */),
+ hid_input, 0, &sc->sc_hid.volume_up_loc, &flags,
+ &sc->sc_hid.volume_up_id)) {
+ if (flags & HIO_VARIABLE)
+ sc->sc_hid.flags |= UAUDIO_HID_HAS_VOLUME_UP;
+ DPRINTFN(1, "Found Volume Up key\n");
+ }
+
+ if (hid_locate(d_ptr, d_len,
+ HID_USAGE2(HUP_CONSUMER, 0xEA /* Volume Decrement */),
+ hid_input, 0, &sc->sc_hid.volume_down_loc, &flags,
+ &sc->sc_hid.volume_down_id)) {
+ if (flags & HIO_VARIABLE)
+ sc->sc_hid.flags |= UAUDIO_HID_HAS_VOLUME_DOWN;
+ DPRINTFN(1, "Found Volume Down key\n");
+ }
+
+ free(d_ptr, M_TEMP);
+
+ if (!(sc->sc_hid.flags & (UAUDIO_HID_HAS_VOLUME_UP |
+ UAUDIO_HID_HAS_VOLUME_DOWN))) {
+ DPRINTFN(1, "Did not find any volume related keys\n");
+ return (-1);
+ }
+
+ /* prevent the uhid driver from attaching */
+ usbd_set_parent_iface(uaa->device, sc->sc_hid.iface_index,
+ sc->sc_mixer_iface_index);
+
+ /* allocate USB transfers */
+ error = usbd_transfer_setup(uaa->device, &sc->sc_hid.iface_index,
+ sc->sc_hid.xfer, uaudio_hid_config, UAUDIO_HID_N_TRANSFER,
+ sc, sc->sc_mixer_lock);
+ if (error) {
+ DPRINTF("error=%s\n", usbd_errstr(error));
+ return (-1);
+ }
+ return (0);
+}
+
+static void
+uaudio_hid_detach(struct uaudio_softc *sc)
+{
+ usbd_transfer_unsetup(sc->sc_hid.xfer, UAUDIO_HID_N_TRANSFER);
+}
+
DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, NULL, 0);
MODULE_DEPEND(uaudio, usb, 1, 1, 1);
MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
Modified: user/attilio/vmc-playground/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- user/attilio/vmc-playground/sys/fs/nfs/nfs_commonkrpc.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/fs/nfs/nfs_commonkrpc.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -1031,7 +1031,6 @@ int newnfs_sig_set[] = {
SIGTERM,
SIGHUP,
SIGKILL,
- SIGSTOP,
SIGQUIT
};
@@ -1052,7 +1051,7 @@ nfs_sig_pending(sigset_t set)
/*
* The set/restore sigmask functions are used to (temporarily) overwrite
- * the process p_sigmask during an RPC call (for example). These are also
+ * the thread td_sigmask during an RPC call (for example). These are also
* used in other places in the NFS client that might tsleep().
*/
void
@@ -1081,8 +1080,10 @@ newnfs_set_sigmask(struct thread *td, si
SIGDELSET(newset, newnfs_sig_set[i]);
}
mtx_unlock(&p->p_sigacts->ps_mtx);
+ sigdeferstop(td);
+ kern_sigprocmask(td, SIG_SETMASK, &newset, oldset,
+ SIGPROCMASK_PROC_LOCKED);
PROC_UNLOCK(p);
- kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, 0);
}
void
@@ -1091,6 +1092,7 @@ newnfs_restore_sigmask(struct thread *td
if (td == NULL)
td = curthread; /* XXX */
kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
+ sigallowstop(td);
}
/*
Modified: user/attilio/vmc-playground/sys/kern/kern_sig.c
==============================================================================
--- user/attilio/vmc-playground/sys/kern/kern_sig.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/kern/kern_sig.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -2364,6 +2364,13 @@ tdsigwakeup(struct thread *td, int sig,
}
/*
+ * Don't awaken a sleeping thread for SIGSTOP if the
+ * STOP signal is deferred.
+ */
+ if ((prop & SA_STOP) && (td->td_flags & TDF_SBDRY))
+ goto out;
+
+ /*
* Give low priority threads a better chance to run.
*/
if (td->td_priority > PUSER)
@@ -2404,12 +2411,13 @@ sig_suspend_threads(struct thread *td, s
if ((TD_IS_SLEEPING(td2) || TD_IS_SWAPPED(td2)) &&
(td2->td_flags & TDF_SINTR)) {
if (td2->td_flags & TDF_SBDRY) {
- if (TD_IS_SUSPENDED(td2))
- wakeup_swapper |=
- thread_unsuspend_one(td2);
- if (TD_ON_SLEEPQ(td2))
- wakeup_swapper |=
- sleepq_abort(td2, ERESTART);
+ /*
+ * Once a thread is asleep with
+ * TDF_SBDRY set, it should never
+ * become suspended due to this check.
+ */
+ KASSERT(!TD_IS_SUSPENDED(td2),
+ ("thread with deferred stops suspended"));
} else if (!TD_IS_SUSPENDED(td2)) {
thread_suspend_one(td2);
}
@@ -2529,6 +2537,34 @@ tdsigcleanup(struct thread *td)
}
+/* Defer the delivery of SIGSTOP for the current thread. */
+void
+sigdeferstop(struct thread *td)
+{
+
+ KASSERT(!(td->td_flags & TDF_SBDRY),
+ ("attempt to set TDF_SBDRY recursively"));
+ thread_lock(td);
+ td->td_flags |= TDF_SBDRY;
+ thread_unlock(td);
+}
+
+/*
+ * Permit the delivery of SIGSTOP for the current thread. This does
+ * not immediately suspend if a stop was posted. Instead, the thread
+ * will suspend either via ast() or a subsequent interruptible sleep.
+ */
+void
+sigallowstop(struct thread *td)
+{
+
+ KASSERT(td->td_flags & TDF_SBDRY,
+ ("attempt to clear already-cleared TDF_SBDRY"));
+ thread_lock(td);
+ td->td_flags &= ~TDF_SBDRY;
+ thread_unlock(td);
+}
+
/*
* If the current process has received a signal (should be caught or cause
* termination, should interrupt current syscall), return the signal number.
@@ -2561,7 +2597,7 @@ issignal(struct thread *td, int stop_all
SIGSETOR(sigpending, p->p_sigqueue.sq_signals);
SIGSETNAND(sigpending, td->td_sigmask);
- if (p->p_flag & P_PPWAIT)
+ if (p->p_flag & P_PPWAIT || td->td_flags & TDF_SBDRY)
SIG_STOPSIGMASK(sigpending);
if (SIGISEMPTY(sigpending)) /* no signal to send */
return (0);
@@ -2677,10 +2713,6 @@ issignal(struct thread *td, int stop_all
(p->p_pgrp->pg_jobc == 0 &&
prop & SA_TTYSTOP))
break; /* == ignore */
-
- /* Ignore, but do not drop the stop signal. */
- if (stop_allowed != SIG_STOP_ALLOWED)
- return (sig);
mtx_unlock(&ps->ps_mtx);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
&p->p_mtx.lock_object, "Catching SIGSTOP");
Modified: user/attilio/vmc-playground/sys/kern/subr_sleepqueue.c
==============================================================================
--- user/attilio/vmc-playground/sys/kern/subr_sleepqueue.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/kern/subr_sleepqueue.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -352,8 +352,6 @@ sleepq_add(void *wchan, struct lock_obje
if (flags & SLEEPQ_INTERRUPTIBLE) {
td->td_flags |= TDF_SINTR;
td->td_flags &= ~TDF_SLEEPABORT;
- if (flags & SLEEPQ_STOP_ON_BDRY)
- td->td_flags |= TDF_SBDRY;
}
thread_unlock(td);
}
@@ -600,7 +598,7 @@ sleepq_check_signals(void)
/* We are no longer in an interruptible sleep. */
if (td->td_flags & TDF_SINTR)
- td->td_flags &= ~(TDF_SINTR | TDF_SBDRY);
+ td->td_flags &= ~TDF_SINTR;
if (td->td_flags & TDF_SLEEPABORT) {
td->td_flags &= ~TDF_SLEEPABORT;
@@ -747,7 +745,7 @@ sleepq_resume_thread(struct sleepqueue *
td->td_wmesg = NULL;
td->td_wchan = NULL;
- td->td_flags &= ~(TDF_SINTR | TDF_SBDRY);
+ td->td_flags &= ~TDF_SINTR;
CTR3(KTR_PROC, "sleepq_wakeup: thread %p (pid %ld, %s)",
(void *)td, (long)td->td_proc->p_pid, td->td_name);
Modified: user/attilio/vmc-playground/sys/kern/vfs_acl.c
==============================================================================
--- user/attilio/vmc-playground/sys/kern/vfs_acl.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/kern/vfs_acl.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -247,7 +247,7 @@ vacl_get_acl(struct thread *td, struct v
struct acl *inkernelacl;
int error;
- inkernelacl = acl_alloc(M_WAITOK);
+ inkernelacl = acl_alloc(M_WAITOK | M_ZERO);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
#ifdef MAC
error = mac_vnode_check_getacl(td->td_ucred, vp, type);
Modified: user/attilio/vmc-playground/sys/nfsclient/nfs_krpc.c
==============================================================================
--- user/attilio/vmc-playground/sys/nfsclient/nfs_krpc.c Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/nfsclient/nfs_krpc.c Wed Feb 6 23:42:04 2013 (r246444)
@@ -699,7 +699,6 @@ int nfs_sig_set[] = {
SIGTERM,
SIGHUP,
SIGKILL,
- SIGSTOP,
SIGQUIT
};
@@ -720,7 +719,7 @@ nfs_sig_pending(sigset_t set)
/*
* The set/restore sigmask functions are used to (temporarily) overwrite
- * the process p_sigmask during an RPC call (for example). These are also
+ * the thread td_sigmask during an RPC call (for example). These are also
* used in other places in the NFS client that might tsleep().
*/
void
@@ -749,8 +748,10 @@ nfs_set_sigmask(struct thread *td, sigse
SIGDELSET(newset, nfs_sig_set[i]);
}
mtx_unlock(&p->p_sigacts->ps_mtx);
+ sigdeferstop(td);
+ kern_sigprocmask(td, SIG_SETMASK, &newset, oldset,
+ SIGPROCMASK_PROC_LOCKED);
PROC_UNLOCK(p);
- kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, 0);
}
void
@@ -759,6 +760,7 @@ nfs_restore_sigmask(struct thread *td, s
if (td == NULL)
td = curthread; /* XXX */
kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
+ sigallowstop(td);
}
/*
Modified: user/attilio/vmc-playground/sys/sys/signalvar.h
==============================================================================
--- user/attilio/vmc-playground/sys/sys/signalvar.h Wed Feb 6 23:30:36 2013 (r246443)
+++ user/attilio/vmc-playground/sys/sys/signalvar.h Wed Feb 6 23:42:04 2013 (r246444)
@@ -328,6 +328,8 @@ extern struct mtx sigio_lock;
#define SIGPROCMASK_PS_LOCKED 0x0004
int cursig(struct thread *td, int stop_allowed);
+void sigdeferstop(struct thread *td);
+void sigallowstop(struct thread *td);
void execsigs(struct proc *p);
void gsignal(int pgid, int sig, ksiginfo_t *ksi);
void killproc(struct proc *p, char *why);
More information about the svn-src-user
mailing list