From 6f07e1ff6bec8f306e8aa1d59b8bcaa93ffa776e Mon Sep 17 00:00:00 2001 From: Rik Faith Date: Sat, 26 Aug 2000 10:36:44 +0000 Subject: Sync with Linux 2.4.0-test7 Add signal blocking support to all drivers (using control-z on a running direct-rendering client should work now) --- linux/lock.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'linux/lock.c') diff --git a/linux/lock.c b/linux/lock.c index 55082727..33b2cc03 100644 --- a/linux/lock.c +++ b/linux/lock.c @@ -223,3 +223,35 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd, drm_flush_unblock(dev, lock.context, lock.flags); return ret; } + +/* If we get here, it means that the process has called DRM_IOCTL_LOCK + without calling DRM_IOCTL_UNLOCK. + + If the lock is not held, then let the signal proceed as usual. + + If the lock is held, then set the contended flag and keep the signal + blocked. + + + Return 1 if the signal should be delivered normally. + Return 0 if the signal should be blocked. */ + +int drm_notifier(void *priv) +{ + drm_sigdata_t *s = (drm_sigdata_t *)priv; + unsigned int old, new, prev; + + + /* Allow signal delivery if lock isn't held */ + if (!_DRM_LOCK_IS_HELD(s->lock->lock) + || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1; + + /* Otherwise, set flag to force call to + drmUnlock */ + do { + old = s->lock->lock; + new = old | _DRM_LOCK_CONT; + prev = cmpxchg(&s->lock->lock, old, new); + } while (prev != old); + return 0; +} -- cgit v1.2.3