rwlock 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTJjZTUxZTcyYmQyZDEwY2Q3ZDY2MmNjODllMjMyNTM1OTkxYzZhYQ==
5
+ data.tar.gz: !binary |-
6
+ OTVlYTlmM2VhOGY0YmU3YTY5ODVjZTlkMjhlY2RhNDE2ZjQ2YTE5Yg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NTIwODgzMWRiNzgxMWM2MDViZjc2MWMxODhhYjNkNTU2YjA4YWY1MGI0MmY3
10
+ NDFkMWEwY2I4NWQ4MmRiNjBlZWNlYTAyN2QwNTE3YWY1YzM5ZmE4ZmQ2YmU5
11
+ ZmZmMmEzNjM5MjI0ZTAzZjM5YjUzMzRjNGJmN2ViM2YwOGFhMjc=
12
+ data.tar.gz: !binary |-
13
+ M2I4ZjdkZmVmMjhmNGYxZjEzOTk0NTBlZTBhMzVjNDc1MjhmODJhZWE1ODhm
14
+ MWFkZGM2OGRlNzY3MTAxYjNhOWM4ODZlODcwN2Y3MTNmNmE5M2E5OTFjN2Zh
15
+ ZmUxMGY4YTBjYzc0OWI2ODU2MjdkOWRiMjc0YmMyZjM4MzI0NDY=
@@ -0,0 +1,87 @@
1
+ require 'thread'
2
+ if defined? require_relative
3
+ require_relative 'rwlock/sized_queue_patch'
4
+ else
5
+ require File.join(File.expand_path(File.dirname(__FILE__)), "rwlock", "sized_queue_patch")
6
+ end
7
+
8
+ # This class provides a simple readers-writer lock (RWLock).
9
+ # A RWLock allows multiple "readers" to access a resource simultaneously
10
+ # but "writers" must have exclusive access. In other words, during a "write"
11
+ # only a single thread may have access to the resource.
12
+ #
13
+ # This RWLock prevents writer starvation. While there are no hard guarantees,
14
+ # if a writer requests access it will generally get access as soon as all
15
+ # current readers are finished.
16
+ #
17
+ # When the current writer is finished, waiting readers have first opportunity
18
+ # to grab the lock. This should result in no starvation of either readers nor
19
+ # writers, although access may not be "fair".
20
+ class RWLock
21
+ # Creates new readers-writers lock.
22
+ # The `max_size` argument limits how many readers may read simultaneously.
23
+ # A limit is necessary to prevent writer starvation.
24
+ def initialize max_size = 10
25
+ @write_lock = Mutex.new
26
+ @q = SizedQueue.new(max_size)
27
+ end
28
+
29
+ # Obtains reading lock and executes block, then releases reading lock.
30
+ # Many calls to RWLock#read_sync may execute in parallel, but wil not
31
+ # overlap with calls to RWLock#write_sync.
32
+ #
33
+ # If the number of readers is currently at the maximum or a write operation
34
+ # is in progress, this method will wait. When a reading spot is available and
35
+ # no write operations are occurring, then the block will be executed.
36
+ #
37
+ # rwl = RWLock.new
38
+ # a = [1, 2, 3]
39
+ #
40
+ # Thread.new do
41
+ # rwl.read_sync do
42
+ # puts a[1]
43
+ # end
44
+ # end
45
+ def read_sync
46
+ @q.push true
47
+ yield
48
+ ensure
49
+ @q.pop
50
+ end
51
+
52
+ # Obtains writing lock and executes block, then releases writing lock.
53
+ # The block will have exclusive access to the lock, with no readers or
54
+ # other writers allowed to execute at the same time.
55
+ #
56
+ # If any readers are executing, the method will wait until the current
57
+ # readers are finished then the block will be executed.
58
+ #
59
+ # If another writer is executing, the method will wait until the current
60
+ # writer is finished. However, readers have first chance at access after a
61
+ # write.
62
+ #
63
+ # rwl = RWLock.new
64
+ # a = [1, 2, 3]
65
+ #
66
+ # Thread.new do
67
+ # rwl.write_sync do
68
+ # a[1] += 1
69
+ # end
70
+ # end
71
+ def write_sync
72
+ @write_lock.synchronize do
73
+ @q.max.times { @q.push true }
74
+
75
+ begin
76
+ yield
77
+ ensure
78
+ @q.clear
79
+ end
80
+ end
81
+ end
82
+
83
+ # Returns the set maximum number of simultaneous readers.
84
+ def max
85
+ @q.max
86
+ end
87
+ end
@@ -0,0 +1,29 @@
1
+ if not SizedQueue.instance_methods(false).include? :clear
2
+ if RUBY_VERSION == "1.9.3" and RUBY_PATCHLEVEL < 545
3
+ class SizedQueue
4
+ # Removes all objects from the queue and wakes waiting threads, if any.
5
+ def clear
6
+ @mutex.synchronize do
7
+ @que.clear
8
+ begin
9
+ until @queue_wait.empty?
10
+ @queue_wait.shift.wakeup
11
+ end
12
+ rescue ThreadError
13
+ retry
14
+ end
15
+ end
16
+ end
17
+ end
18
+ elsif RUBY_VERSION == "2.0.0"
19
+ class SizedQueue
20
+ # Removes all objects from the queue and wakes waiting threads, if any.
21
+ def clear
22
+ @mutex.synchronize do
23
+ @que.clear
24
+ @enque_cond.signal
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rwlock
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Justin Collins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Simple thread-level readers-writer lock in pure Ruby. Allows multiple
14
+ readers to access a resource while writers get exclusive access.
15
+ email:
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/rwlock.rb
21
+ - lib/rwlock/sized_queue_patch.rb
22
+ homepage: https://github.com/presidentbeef/rwlock
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.2.2
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Simple readers-writer lock.
46
+ test_files: []