Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Lu Xu
erp5
Commits
7079082b
Commit
7079082b
authored
Dec 22, 2017
by
Tomáš Peterka
Committed by
Tomáš Peterka
Dec 22, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[renderjs_ui] Add non-recursive locking for gadgets into gadget_global
/reviewed-on
nexedi/erp5!536
parent
f09062e5
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
113 additions
and
2 deletions
+113
-2
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_global_js.js
.../PathTemplateItem/web_page_module/rjs_gadget_global_js.js
+111
-0
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_global_js.xml
...PathTemplateItem/web_page_module/rjs_gadget_global_js.xml
+2
-2
No files found.
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_global_js.js
View file @
7079082b
...
...
@@ -126,4 +126,115 @@
});
};
/** Internal function to prepare gadget to hold a mutex */
function
ensureLockable
(
gadget
)
{
if
(
gadget
.
props
===
undefined
)
{
gadget
.
props
=
{};
}
// waiting_line is container of mutexes which already blocks some Promise
if
(
gadget
.
props
.
waiting_line
===
undefined
)
{
gadget
.
props
.
waiting_line
=
[];
}
}
/** Synchronously lock gadget and return previous lock's promise.
NON-RECURSIVE lock! If you lock inside locked execution you will wait forever.
If used in a Queue (@see lockGadgetInQueue) it blocks when acquiring the lock.
*/
window
.
lockGadget
=
function
(
gadget
)
{
var
ahead_of_me
;
ensureLockable
(
gadget
);
// step in line
gadget
.
props
.
waiting_line
.
push
(
RSVP
.
defer
());
if
(
gadget
.
props
.
waiting_line
.
length
>=
2
)
{
// wait for the promise ahead of me
ahead_of_me
=
gadget
.
props
.
waiting_line
[
gadget
.
props
.
waiting_line
.
length
-
2
].
promise
;
}
else
{
ahead_of_me
=
RSVP
.
resolve
();
}
// return previous lock's Promise to postpone execution
return
ahead_of_me
;
};
/** Lock gadget as a step in RSVP.Queue waiting for previous lock to unlock.
Use in RSVP.Queue to block execution until manually called `unlockGadget`.
Both lock/unlockGadget pass through any value in RSVP.Queue manner.
Pass through any value.
Example:
new RSVP.Queue()
.push(function () {return some_value;})
.push(lockGadgetInQueue(gadget), lockGadgetInFailedQueue(gadget))
.push(function (some_value) {return someWork(some_value);})
.push(unlockGadgetInQueue(gadget), unlockGadgetInFailedQueue(gadget));
*/
window
.
lockGadgetInQueue
=
function
(
gadget
)
{
// return function to be used in RSVP.Queue
return
function
(
pass_through
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
window
.
lockGadget
(
gadget
);
})
.
push
(
function
()
{
return
pass_through
;
});
};
};
/** Lock Gagdet in Queue but intended to be used in "fail" branch (the second function).
Rethrows any argument.
*/
window
.
lockGadgetInFailedQueue
=
function
(
gadget
)
{
// return function to be used in RSVP.Queue
return
function
(
error
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
window
.
lockGadget
(
gadget
);
})
.
push
(
function
()
{
throw
error
;
});
};
};
/** Synchronously unlock gadget by resolving props.mutex.promise.
That promise is most likely blocking some RSVP.Queue or is then-ed on another
Promise.
*/
window
.
unlockGadget
=
function
(
gadget
)
{
if
(
gadget
.
props
===
undefined
||
gadget
.
props
.
waiting_line
===
undefined
||
gadget
.
props
.
waiting_line
.
length
===
0
)
{
throw
new
Error
(
"
Gadget
"
+
gadget
+
"
is not locked!
"
);
}
gadget
.
props
.
waiting_line
.
shift
().
resolve
();
};
/** Unlock gadget without blocking as a step in RSVP.Queue.
Pass through any value. Not re-throwing errors in fail branch!
For example @see lockGadgetInQueue.
*/
window
.
unlockGadgetInQueue
=
function
(
gadget
)
{
return
function
(
pass_through
)
{
window
.
unlockGadget
(
gadget
);
return
pass_through
;
};
};
/** Unlock gadget without blocking and throw any argument received. */
window
.
unlockGadgetInFailedQueue
=
function
(
gadget
)
{
return
function
(
error
)
{
window
.
unlockGadget
(
gadget
);
throw
error
;
};
};
}(
window
,
RSVP
,
FileReader
));
\ No newline at end of file
bt5/erp5_web_renderjs_ui/PathTemplateItem/web_page_module/rjs_gadget_global_js.xml
View file @
7079082b
...
...
@@ -230,7 +230,7 @@
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
9
47.51167.64410.14796
</string>
</value>
<value>
<string>
9
64.19771.1861.12424
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
...
...
@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>
1
450099422.01
</float>
<float>
1
513956134.36
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
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