From: ctm@... (Clifford T. Matthews) Date: 2006-09-29T02:10:52+09:00 Subject: continuations across fork? I wrote some code that deliberately uses continuations that cross a fork boundary. When I went to test it, I was surprised by the error: "continuation called across trap". I can think of a few reasons why people might not want to use continuations across fork, but not knowing Ruby internals particularly well, I couldn't see a reason why it should be absolutely prohibited. Curious person that I am, I removed the test at the beginning of rb_cont_call in eval.c, and my program ran like it was supposed to. If I were more familiar with Ruby's internals, I'd be asking my question on ruby-core, but I figure that if there's a super obvious reason why continuations aren't allowed across fork, someone here would be able to point it out. My reason for experimenting with this isn't purely theoretical. Ruby's IO system (at least under Linux) uses fd_set, which limits the number of open file descriptors to 1024. Using send_io and recv_io, I can trivially write a forking server that uses a pool of children to collectively have more than 1024 connections open at once. The parent does the accept, then sends the fd down to a child. However, I want my connections to be DRb connections on top of certificate-verifying SSL, and I want my certificate password protected. When I've done this before in C, I've used SSL_CTX_set_default_passwd_cb. That allows me to read in the password once, and then distribute that password multiple times before destroying it. Ruby's OpenSSL implementation doesn't use or expose SSL_CTX_set_default_passwd_cb, so I had the idea of "chopping" DRb's start_service so that the password reading would be done once in the parent. By using continuations, I could then fork my children and have each of them finish start_service, with the certificate already unlocked. I realize there are several other things I could do other than the above. However, I coded up my solution without realizing that you can't call a continuation across fork. Now I'm curious why it's disallowed. -- Cliff Matthews P.S., if anyone wants to see my proof-of-concept server, I don't mind sharing the code. The trick is to redefine DRb::DRbTCPSocket.open_server_inaddr_any to save its context before going to the context to do the forks. However, since this is DRb implementation specific and since continuations across forks aren't actually allowed, my code is more of a curiosity to be poked with ten foot pole.