diff options
author | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2000-09-06 12:11:57 +0000 |
---|---|---|
committer | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2000-09-06 12:11:57 +0000 |
commit | 68380d1373cf7b01a6ae5c9440de7a52745af091 (patch) | |
tree | 42c623666b8746dae59e7ed2423a19ebaa68b9cd /linux/lock.c | |
parent | a2020a33349c91a0036b1fde8ae0d0229ae8e005 (diff) |
Merge trunk into tdfx-2-1-branchtdfx-2-1-20000906
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; +} |