Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
renderjs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
renderjs
Commits
b72c73a8
Commit
b72c73a8
authored
May 16, 2018
by
Romain Courteaud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Speed up mutex.
parent
4499150f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
26 additions
and
119 deletions
+26
-119
renderjs.js
renderjs.js
+14
-41
test/mutex_test.js
test/mutex_test.js
+12
-78
No files found.
renderjs.js
View file @
b72c73a8
...
...
@@ -185,51 +185,22 @@
if
(
!
(
this
instanceof
Mutex
))
{
return
new
Mutex
();
}
this
.
_latest_
defer
=
null
;
this
.
_latest_
promise
=
null
;
};
Mutex
.
prototype
=
{
constructor
:
Mutex
,
lock
:
function
lockMutex
()
{
var
previous_defer
=
this
.
_latest_defer
,
current_defer
=
RSVP
.
defer
(),
queue
=
new
RSVP
.
Queue
();
this
.
_latest_defer
=
current_defer
;
if
(
previous_defer
!==
null
)
{
queue
.
push
(
function
acquireMutex
()
{
return
previous_defer
.
promise
;
lockAndRun
:
function
lockMutexAndRun
(
callback
)
{
var
previous_promise
=
this
.
_latest_promise
;
if
(
previous_promise
===
null
)
{
this
.
_latest_promise
=
RSVP
.
resolve
(
callback
());
}
else
{
this
.
_latest_promise
=
this
.
_latest_promise
.
always
(
function
()
{
return
callback
();
});
}
// Create a new promise (.then) not cancellable
// to allow external cancellation of the callback
// without breaking the mutex implementation
queue
.
fail
(
current_defer
.
resolve
.
bind
(
current_defer
));
return
queue
.
push
(
function
generateMutexUnlock
()
{
return
function
runAndUnlock
(
callback
)
{
return
ensurePushableQueue
(
callback
)
.
push
(
function
releaseMutexAfterSuccess
(
result
)
{
current_defer
.
resolve
(
result
);
return
result
;
},
function
releaseMutexAfterError
(
error
)
{
current_defer
.
resolve
(
error
);
throw
error
;
});
};
});
},
lockAndRun
:
function
(
callback
)
{
return
this
.
lock
()
.
push
(
function
executeLockAndRunCallback
(
runAndUnlock
)
{
return
runAndUnlock
(
callback
);
});
return
this
.
_latest_promise
;
}
};
...
...
@@ -671,7 +642,9 @@
if
(
!
context
.
hasOwnProperty
(
mutex_name
))
{
context
[
mutex_name
]
=
new
Mutex
();
}
return
context
[
mutex_name
].
lockAndRun
(
waitForMethodCallback
);
return
ensurePushableQueue
(
context
[
mutex_name
].
lockAndRun
,
[
waitForMethodCallback
],
context
[
mutex_name
]);
}
return
ensurePushableQueue
(
callback
,
argument_list
,
context
);
};
...
...
test/mutex_test.js
View file @
b72c73a8
...
...
@@ -152,14 +152,17 @@
var
mutex
=
new
Mutex
(),
counter
=
0
;
stop
();
expect
(
4
);
expect
(
5
);
function
assertCounter
(
value
)
{
equal
(
counter
,
value
);
counter
+=
1
;
}
function
callback1
()
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
assertCounter
(
0
);
throw
new
Error
(
'
error in callback1
'
);
});
}
function
callback2
()
{
assertCounter
(
1
);
...
...
@@ -179,7 +182,7 @@
})
.
push
(
undefined
,
function
(
error
)
{
equal
(
error
.
message
,
'
error in callback1
'
);
assertCounter
(
2
);
assertCounter
(
3
);
})
.
always
(
function
()
{
start
();
...
...
@@ -196,7 +199,10 @@
counter
+=
1
;
}
function
callback1
()
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
ok
(
false
,
'
Should not reach that code
'
);
});
}
function
callback2
()
{
assertCounter
(
1
);
...
...
@@ -208,7 +214,7 @@
return
RSVP
.
all
([
promise1
.
then
(
function
()
{
ok
(
false
,
'
Should not reach that code
'
);
ok
(
false
,
'
Should not reach that code
2
'
);
},
function
(
error
)
{
assertCounter
(
0
);
equal
(
error
.
message
,
'
Default Message
'
);
...
...
@@ -288,76 +294,4 @@
});
});
test
(
'
lockAndRun only wait for the callback
'
,
function
()
{
var
mutex
=
new
Mutex
(),
counter
=
0
;
stop
();
expect
(
4
);
function
assertCounter
(
value
)
{
equal
(
counter
,
value
);
counter
+=
1
;
}
function
callback1
()
{
assertCounter
(
0
);
return
'
callback1 result
'
;
}
function
callback2
()
{
assertCounter
(
1
);
return
'
callback2 result
'
;
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
RSVP
.
any
([
mutex
.
lockAndRun
(
callback1
)
.
push
(
function
()
{
return
RSVP
.
delay
(
10000
);
}),
mutex
.
lockAndRun
(
callback2
)
]);
})
.
push
(
function
(
result
)
{
equal
(
result
,
'
callback2 result
'
);
assertCounter
(
2
);
})
.
always
(
function
()
{
start
();
});
});
test
(
'
lockAndRun only wait for the error callback
'
,
function
()
{
var
mutex
=
new
Mutex
(),
counter
=
0
;
stop
();
expect
(
4
);
function
assertCounter
(
value
)
{
equal
(
counter
,
value
);
counter
+=
1
;
}
function
callback1
()
{
assertCounter
(
0
);
throw
new
Error
(
'
callback1 error
'
);
}
function
callback2
()
{
assertCounter
(
1
);
return
'
callback2 result
'
;
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
RSVP
.
any
([
mutex
.
lockAndRun
(
callback1
)
.
push
(
undefined
,
function
()
{
return
RSVP
.
delay
(
10000
);
}),
mutex
.
lockAndRun
(
callback2
)
]);
})
.
push
(
function
(
result
)
{
equal
(
result
,
'
callback2 result
'
);
assertCounter
(
2
);
})
.
always
(
function
()
{
start
();
});
});
}(
renderJS
.
Mutex
,
QUnit
));
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment