diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-10-29 17:06:48 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-10-29 17:06:48 -0700 |
commit | ef69c56c82e85e83014605f501110697d81bcdc1 (patch) | |
tree | 7d1794a21701db7ecac84f747d165470daba7fc2 | |
parent | 358aa35d306571511a4a8027d7033ffe37e8812d (diff) | |
download | mu-ef69c56c82e85e83014605f501110697d81bcdc1.tar.gz |
3608 - concurrent writes to fake file system
-rw-r--r-- | 075channel.mu | 4 | ||||
-rw-r--r-- | 088file.mu | 6 | ||||
-rw-r--r-- | 089scenario_filesystem.cc | 2 |
3 files changed, 10 insertions, 2 deletions
diff --git a/075channel.mu b/075channel.mu index a023b294..985292a3 100644 --- a/075channel.mu +++ b/075channel.mu @@ -9,6 +9,10 @@ # b) Writing to a channel implicitly performs a deep copy. This prevents # addresses from being shared between routines, and therefore eliminates all # possibility of race conditions. +# +# There's still a narrow window for race conditions: the ingredients passed in +# to 'start-running'. Pass only channels into routines and you should be fine. +# Any other mutable ingredients will require locks. scenario channel [ run [ diff --git a/088file.mu b/088file.mu index 3c31e66f..de374f1f 100644 --- a/088file.mu +++ b/088file.mu @@ -2,6 +2,7 @@ # are thus easier to test. container resources [ + lock:bool data:&:@:resource ] @@ -84,7 +85,6 @@ def start-writing resources:&:resources, filename:text -> sink:&:sink:char, rout { break-unless resources # fake file system - # beware: doesn't support multiple concurrent writes yet routine-id <- start-running transmit-to-fake-file resources, filename, source reply } @@ -109,6 +109,8 @@ def transmit-to-file file:num, source:&:source:char -> source:&:source:char [ def transmit-to-fake-file resources:&:resources, filename:text, source:&:source:char -> resources:&:resources, source:&:source:char [ local-scope load-ingredients + lock:location <- get-location *resources, lock:offset + wait-for-reset-then-set lock # compute new file contents buf:&:buffer <- new-buffer 30 { @@ -133,6 +135,7 @@ def transmit-to-fake-file resources:&:resources, filename:text, source:&:source: found?:bool <- equal filename, curr-filename loop-unless found? put-index *data, i, new-resource + reset lock reply } # if file didn't already exist, make room for it @@ -149,4 +152,5 @@ def transmit-to-fake-file resources:&:resources, filename:text, source:&:source: } # write new file put-index *new-data, len, new-resource + reset lock ] diff --git a/089scenario_filesystem.cc b/089scenario_filesystem.cc index 6af3166b..dfbc245d 100644 --- a/089scenario_filesystem.cc +++ b/089scenario_filesystem.cc @@ -224,7 +224,7 @@ void construct_resources_object(const map<string, string>& contents) { trace(9999, "mem") << "storing refcount 1 in location " << resources_data_address << end(); // wrap the resources data in a 'resources' object int resources_address = allocate(size_of_resources()); - curr = resources_address+/*skip refcount*/1; + curr = resources_address+/*skip refcount*/1+/*offset of 'data' element*/1; put(Memory, curr, resources_data_address); trace(9999, "mem") << "storing resources data address " << resources_data_address << " in location " << curr << end(); put(Memory, resources_address, 1); // initialize refcount |