diff options
author | Rik Faith <faith@alephnull.com> | 2000-08-26 10:36:44 +0000 |
---|---|---|
committer | Rik Faith <faith@alephnull.com> | 2000-08-26 10:36:44 +0000 |
commit | 6f07e1ff6bec8f306e8aa1d59b8bcaa93ffa776e (patch) | |
tree | 334961bb4f9cc7c83b95a17d6d79f3bf351bbacf /linux/lock.c | |
parent | 37643234affb329775d3330eed650dee59d39bad (diff) |
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)
Diffstat (limited to 'linux/lock.c')
-rw-r--r-- | linux/lock.c | 32 |
1 files changed, 32 insertions, 0 deletions
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; +} |