summaryrefslogtreecommitdiff
path: root/load.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-12-13 07:13:31 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-12-13 07:13:31 +0000
commitab6c8910f47a2b95f7338a182715ee0bee5ec45d (patch)
treed7691af9df1fbba665fc00009dea147af3a2eb31 /load.c
parentddc15717ccb98d57a5b82b4138b1dc97375e4ac2 (diff)
* load.c (load_unlock): all threads requiring one file should
share same loading barrier, so it must be kept alive while those are waiting on it. [ruby-core:41618] [Bug #5754] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'load.c')
-rw-r--r--load.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/load.c b/load.c
index 9f09dd548d..9d389f9efb 100644
--- a/load.c
+++ b/load.c
@@ -415,10 +415,12 @@ load_unlock(const char *ftptr, int done)
st_data_t key = (st_data_t)ftptr;
st_data_t data;
st_table *loading_tbl = get_loading_table();
+ VALUE barrier;
- if (st_delete(loading_tbl, &key, &data)) {
- VALUE barrier = (VALUE)data;
- xfree((char *)key);
+ if (!st_lookup(loading_tbl, key, &data)) return;
+ barrier = (VALUE)data;
+ if (rb_barrier_waiting(barrier) ||
+ (st_delete(loading_tbl, &key, &data) && (xfree((char *)key), 1))) {
if (done)
rb_barrier_destroy(barrier);
else