Hello List,
I had a hard time figuring out why my app running on LispWorks 6.0 couldn't receive and send messages via multiple UDP sockets concurrently until I discovered that a global lock was used on global recv/send buffers.
Is there any reason why global recv/send buffers are used?
The attached patch fixes the problem. Tested with LispWorks 6.0.
--ska
Hello, Kamil Shakirov
Thank you for your work. You do this right. For your question, actually it's a long story:
As you know, LispWorks doesn't provide any UDP support in its COMM package. Current UDP support in USOCKET trunk was from my LispWorks-UDP package [1], and the function SEND-MESSAGE, RECEIVE-MESSAGE, ... was just copied from there.
LispWorks-UDP's API was designed to be similar with the TCP interface in LispWorks' COMM package: there's no OO, raw socket fd was used to handle networking operations. Therefore, I have to make a hard choice between following two options:
1. Use global receive and send buffers with locks to protect them from concurrent access. 2. Create local buffers for SEND-MESSAGE and RECEIVE-MESSAGE when every time they're called. (FLI need special created static array, so cannot just simplify pass the argument to FLI functions)
Obviously, option 2 is not acceptable, too much cost. But I do have some thoughts on concurrent recv/send: I've made the lock as special variables, and user can supply their pre-created buffers for used by SEND-MESSAGE and RECEIVE-MESSAGE. So, if you have multiple threads, just create per-threaded buffers and specially bounded locks (but useless in this case), and it's possible to do concurrent recv/send.
Unfortunately, when these work are merged into USOCKET, no correspond USOCKET API can fit above design, and the design itself is not good at all.
USOCKET has a OO based design, each UDP datagram socket object actually could/should have it's own buffers. I didn't realize this until I saw you solution ... sorry for letting you take time and figure out the correct way to have these buffers.
This is obviously the most important work for UDP/LispWorks support after initial commit in USOCKET. I'll make sure you appear in our release notes and let others take advantage of your work. Your patch was just merged into USOCKET trunk (r570).
Best Regards,
Chun Tian (binghe)
[1] http://common-lisp.net/projects/cl-net-snmp/lispworks.html
在 2010-12-7,19:01, Kamil Shakirov 写道:
Hello List,
I had a hard time figuring out why my app running on LispWorks 6.0 couldn't receive and send messages via multiple UDP sockets concurrently until I discovered that a global lock was used on global recv/send buffers.
Is there any reason why global recv/send buffers are used?
The attached patch fixes the problem. Tested with LispWorks 6.0.
--ska <0001-Enable-mutiple-UDP-sockets.patch>_______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel
Hi Chun,
On Wed, 2010-12-08 at 13:08 +0800, Chun Tian (binghe) wrote:
Hello, Kamil Shakirov
Thank you for your work. You do this right. For your question, actually it's a long story:
As you know, LispWorks doesn't provide any UDP support in its COMM package. Current UDP support in USOCKET trunk was from my LispWorks-UDP package [1], and the function SEND-MESSAGE, RECEIVE-MESSAGE, ... was just copied from there.
LispWorks-UDP's API was designed to be similar with the TCP interface in LispWorks' COMM package: there's no OO, raw socket fd was used to handle networking operations. Therefore, I have to make a hard choice between following two options:
- Use global receive and send buffers with locks to protect them from concurrent access.
- Create local buffers for SEND-MESSAGE and RECEIVE-MESSAGE when every time they're called. (FLI need special created static array, so cannot just simplify pass the argument to FLI functions)
Obviously, option 2 is not acceptable, too much cost. But I do have some thoughts on concurrent recv/send: I've made the lock as special variables, and user can supply their pre-created buffers for used by SEND-MESSAGE and RECEIVE-MESSAGE. So, if you have multiple threads, just create per-threaded buffers and specially bounded locks (but useless in this case), and it's possible to do concurrent recv/send.
Unfortunately, when these work are merged into USOCKET, no correspond USOCKET API can fit above design, and the design itself is not good at all.
USOCKET has a OO based design, each UDP datagram socket object actually could/should have it's own buffers. I didn't realize this until I saw you solution ... sorry for letting you take time and figure out the correct way to have these buffers.
This is obviously the most important work for UDP/LispWorks support after initial commit in USOCKET. I'll make sure you appear in our release notes and let others take advantage of your work. Your patch was just merged into USOCKET trunk (r570).
Thanks for the explanation, i am new to LispWorks. Looking forward to the next Quicklisp update. :)
Best Regards,
Chun Tian (binghe)
[1] http://common-lisp.net/projects/cl-net-snmp/lispworks.html
在 2010-12-7,19:01, Kamil Shakirov 写道:
Hello List,
I had a hard time figuring out why my app running on LispWorks 6.0 couldn't receive and send messages via multiple UDP sockets concurrently until I discovered that a global lock was used on global recv/send buffers.
Is there any reason why global recv/send buffers are used?
The attached patch fixes the problem. Tested with LispWorks 6.0.
--ska <0001-Enable-mutiple-UDP-sockets.patch>_______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel
--ska
This is obviously the most important work for UDP/LispWorks support after initial commit in USOCKET. I'll make sure you appear in our release notes and let others take advantage of your work. Your patch was just merged into USOCKET trunk (r570).
Thanks for the explanation, i am new to LispWorks. Looking forward to the next Quicklisp update. :)
As I know, QuickLisp just refer to USOCKET SVN trunk. You don't need to wait for its update, I think:)
--binghe