Thread: child process exits and closes parent's connections

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445

    child process exits and closes parent's connections

    I have a server that spawns a separate process to handle credit card transactions (64-bit server, but the credit card library is only available in 32-bit form), and when the child process ends, it closes the server instance's network connection and database connection because it co-owns the file descriptors that represent those connections. is there any way I can prevent this from happening? I don't care if the child closes its own copies of the descriptors, but it would be nice if I could prevent it from closing the parent's connections.

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Code:
    fd = open("myfile", O_RDWR);
    if ((pid = fork()) == 0){
            callsomething();
    }
    callsomethingelse();
    return 0;
    It is my understanding that in the example above that fd would have been "opened" twice. If, however, you open myfile from within callsomething() or callsomethingelse(), you'd not have a common file descriptor. How is your code written? Does it do the above or does only the child open the database?

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Kennedy View Post
    Does it do the above or does only the child open the database?
    the parent opens the database connection. and when the child exits, it closes that connection.

  4. #4
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    By that I'm assuming that you mean the parent opens the connection above where you do your fork(). Does the child actually perform a close operation to the connection?

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I'm actually working on a network client right now that needs to share it's connected socket amongst multiple process which are temporary. I'm using pthreads and just made the socket fd a global and this works fine.

    If you haven't used pthreads before, it is very very simple to substitute it for fork in this circumstance. You just make your process a function and launch it this way:
    Code:
    pthread_t mythread;
    pthread_create(&mythread,NULL,myfunc,NULL);
    pthread_detach(mythread);
    At the end of myfunc() (which must be void *) you need:
    Code:
    pthread_exit(NULL);
    You can pass myfunc initial data (via the last pointer in pthread_create), so you don't even need to use a global if that's an issue.

    You could switch over to that sort of model quite easily I think, it would not require many changes, and it gives you some more interesting opportunities too...
    Last edited by MK27; 09-04-2009 at 11:34 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Kennedy View Post
    By that I'm assuming that you mean the parent opens the connection above where you do your fork(). Does the child actually perform a close operation to the connection?
    the parent opens the connection to the database when the request comes in from the client. the child simply inherits it as any child process inherits its parent's open descriptors. the child does not explicitly close it, but the system closes descriptors automatically when the process exits. and because the child's descriptors refer to the same connections as the parent's, it closes the parent's connections as well.

    MK27: I can't use pthreads because the credit card processing program runs as a 32-bit process, while the parent is 64-bit, and the credit card processing library is only available as a 32-bit library, so I can't link it into my main program. it has to be a separate process.

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Elkvis View Post
    MK27: I can't use pthreads because the credit card processing program runs as a 32-bit process, while the parent is 64-bit, and the credit card processing library is only available as a 32-bit library, so I can't link it into my main program. it has to be a separate process.
    Ouch.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by MK27 View Post
    Ouch.
    I've done my damnedest to get the software vendor to recompile it for 64-bit or to give me the source so I can, but it just isn't going to happen short of my company entering into an NDA and forking (no pun intended) over thousands of dollars.

  9. #9
    Registered User
    Join Date
    Oct 2007
    Posts
    32
    Quote Originally Posted by Elkvis View Post
    I have a server that spawns a separate process to handle credit card transactions (64-bit server, but the credit card library is only available in 32-bit form), and when the child process ends, it closes the server instance's network connection and database connection because it co-owns the file descriptors that represent those connections. is there any way I can prevent this from happening? I don't care if the child closes its own copies of the descriptors, but it would be nice if I could prevent it from closing the parent's connections.

    Did child need those or any other file descriptors from parents at all ?

    If not - and assuming your are using Linux (who use something else for servers anyway
    you can instead of fork use clone with flag CLONE_FILES turn off
    In this case parent and child will not share file descriptors.

    If child really uses some file descriptors from parent, then turning of CLONE_FILES is not an option.
    In this case you can write small shared libraries and run your child process with this libraries LD_PRELOADed.

    Shared library should implement 'close' function. Those function should do nothing for
    network connection and database connection file descriptors and behaves like original close for any other

  10. #10
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Valery Reznic View Post
    Did child need those or any other file descriptors from parents at all ?

    If not - and assuming your are using Linux (who use something else for servers anyway
    you can instead of fork use clone with flag CLONE_FILES turn off
    In this case parent and child will not share file descriptors.

    If child really uses some file descriptors from parent, then turning of CLONE_FILES is not an option.
    In this case you can write small shared libraries and run your child process with this libraries LD_PRELOADed.

    Shared library should implement 'close' function. Those function should do nothing for
    network connection and database connection file descriptors and behaves like original close for any other
    the child has absolutely no need of the socket or the db connection; however, the sticky part of this whole thing is that the parent communicates with the child through a pipe via popen(), so at least SOME file descriptors need to be cloned. unfortunately, I can't choose which ones, so it's all or nothing.

    in any case, I've come up with a pretty workable solution to this problem. I'm going to re-write the credit card processor as a standalone server that listens on a unix-domain socket (AF_UNIX) and then I won't have to worry about it. the two processes will be unrelated, and therefore, share no file descriptors, and my problem will magically disappear.

  11. #11
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    It almost sounds like you need a third process running that communicates with your DB. Let the parent communicate with that process and fork children as necessary. Then the child process doesn't get that opened connection ever.

  12. #12
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Kennedy View Post
    It almost sounds like you need a third process running that communicates with your DB. Let the parent communicate with that process and fork children as necessary. Then the child process doesn't get that opened connection ever.
    close.

    the existing server code will run as it always has, and the credit card processing program will be its own standalone server program (the new process) that can listen on a unix-domain socket and handle requests to process card transactions.

Popular pages Recent additions subscribe to a feed