Hey guys,
I've been working on some server code in Gambit. One of my projects uses TCP-SERVICE-REGISTER! to start a service. The problem with this is that when I go to run the program, Gambit doesn't wait for all threads to exit by default, so my program immediately exists. I've seen people add a (##repl-debug-main) call at the end of the script to keep the program going, but there are several IO issues with doing this. I would like to simply:
* Tell Gambit to wait for all threads to exit before exiting OR * Get the thread for the tcp service and join on it OR * Write a function which joins on all threads
The third option is a bit mysterious to me. I'm not sure how to get all threads safely, but here was an attempt. This is pseudo-code basically. The problem with this code is that threads may exit after I have put them into my list but before I call join on them.
(define (thread-join-all!) (let* ((threads (vector->list (thread-group->thread-vector (thread-thread-group (current-thread)))))) (for-each (lambda (el) (if (not (eq? el (current-thread))) (thread-join! el))) threads)))
What would be the best way to join on the threads created by TCP-SERVICE-REGISTER! ?
Afficher les réponses par date
The problem with this code is that threads may exit after I have put them into my list but before I call join on them.
I don't see why that would be a problem, thread-join! will work as well on exited threads.
However I guess you'll have to call tcp-service-unregister! before getting the list of threads or there can new threads be created before you're done joining those from the list.
Christian.
On Wed, Nov 18, 2009 at 3:13 PM, Christian Jaeger chrjae@gmail.com wrote:
The problem with this code is that threads may exit after I have put them into my list but before I call join on them.
I don't see why that would be a problem, thread-join! will work as well on exited threads.
Good to know. I didn't know if the behavior was defined.
However I guess you'll have to call tcp-service-unregister! before getting the list of threads or there can new threads be created before you're done joining those from the list.
You could also keep looping as long as threads exist (excluding the primordial one of course).
Interestingly, it looks like the thread created by TCP-SERVICE-REGISTER! isn't included in the the thread group linked to the originating thread (I'm assuming this because it's not in the returned list of threads from the code in my original email). I forget the semantics of thread groups. Maybe I should figure out how to get a list of all threads disregarding groups.
Thanks, James
Interestingly, it looks like the thread created by TCP-SERVICE-REGISTER! isn't included in the the thread group linked to the originating thread
According to the docs you can define your own thread-group and specify that it should use it (I haven't tried):
(tcp-service-register! port-number-or-address-or-settings thunk [thread-group]) procedure
Christian.
On Wed, Nov 18, 2009 at 5:24 PM, Christian Jaeger chrjae@gmail.com wrote:
According to the docs you can define your own thread-group and specify that it should use it (I haven't tried):
Thanks Christian. It still doesn't seem to work. I wonder if this is the wrong behavior:
(tcp-service-register! 10000 values (thread-thread-group (current-thread))) (vector->list (thread-group->thread-vector (thread-thread-group (current-thread))))
--output--
(#<thread #1 primordial>)
Also, are you receiving duplicates of my emails? I'm getting 2 duplicates for some reason each time I send one to the list, and I can't see why unless it's a problem with the mailing list. If everyone is receiving duplicates, I'm terribly sorry.
- James
.. It still doesn't seem to work. .. .. (thread-thread-group (current-thread)))
Well, I'm not sure which thread(s) you want to see; what I was implicitely suggesting is create a *new* group and then give that to |tcp-service-register!|. See the following; although it doesn't make any difference, you only don't need to filter out other threads anymore; I do see threads created by the tcp service when connections are coming in; but there does not seem to be any tcp service "master thread"; dunno why, maybe the implementation works without using a thread. If your problem is that you don't see any master thread, then why would you want it? I'd expect it never exits (except when running tcp-service-unregister!), so why would you want to join it?
(tcp-service-register! 10000 (lambda args (pp args)(thread-sleep!
10)) (thread-thread-group (current-thread)))
(vector->list (thread-group->thread-vector (thread-thread-group
(current-thread)))) (#<thread #1 primordial>) $ telnet localhost 10000
()
(vector->list (thread-group->thread-vector (thread-thread-group (current-thread)))) (#<thread #1 primordial> #<thread #3 #<input-output-port #4 (tcp-client)>>)
and with the new group:
(define g (make-thread-group "my-tgroup")) (vector->list (thread-group->thread-vector g))
()
(tcp-service-register! 10000 (lambda args (pp args)(thread-sleep! 10)) g)
$ telnet localhost 10000
()
(vector->list (thread-group->thread-vector g)) (#<thread #5 #<input-output-port #6 (tcp-client)>>)
Also, are you receiving duplicates of my emails? I'm getting 2 duplicates for some reason each time I send one to the list,
I'm not getting duplicates from you, neither do gname nor the archive at umontreal show any; you're probably seeing the same as I do in gmail, your replies don't group into the same threads for some reason (and I've checked that in-reply-to is there and correct) whereas the outgoing mail *is* grouping into the original thread, so this looks like a gmail web interface bug.
On Wed, Nov 18, 2009 at 7:40 PM, Christian Jaeger chrjae@gmail.com wrote:
.. It still doesn't seem to work. .. .. (thread-thread-group (current-thread)))
Well, I'm not sure which thread(s) you want to see; what I was implicitely suggesting is create a *new* group and then give that to |tcp-service-register!|. See the following; although it doesn't make any difference, you only don't need to filter out other threads anymore...
Oh, good idea.
If your problem is that you don't see any master thread, then why would you want it? I'd expect it never exits (except when running tcp-service-unregister!), so why would you want to join it?
I'd be interested to know how it works without a master thread, but you're right, basically I don't ever want the program to exit unless I send it some sort of signal. Putting a (thread-sleep! +inf.0) at the end of the script basically does what I'm looking for. Thanks for hashing through my problem.
I'm not getting duplicates from you, neither do gname nor the archive at umontreal show any...
Good, I won't feel like I'm littering the list then! This didn't used to happen, strange.
- James