There's no real difference between C code and perl code when it comes
to fork.
Cool. I'm going to continue to remain largely ignorant of threads then, since they scare me...
There are some things to keep in mind though. Anything that needs things that are different in the child will need to be handled properly. If the TcpServer object stores PID, that's not good.
It doesn't; only the parent tracks the PID (in forkserver). It seems to be sufficient to just do the following:
=== qpsmtpd-forkserver ================================================================== --- qpsmtpd-forkserver (revision 465) +++ qpsmtpd-forkserver (local) @@ -91,8 +91,8 @@ $> = $quid;
# Load plugins here -my $plugin_loader = Qpsmtpd::TcpServer->new(); -$plugin_loader->load_plugins; +my $qpsmtpd = Qpsmtpd::TcpServer->new(); +$qpsmtpd->load_plugins;
::log(LOGINFO,"Listening on port $PORT");
::log(LOGINFO, 'Running as user '.
@@ -173,7 +173,6 @@
POSIX::dup2(fileno($client), 0);
POSIX::dup2(fileno($client), 1);- my $qpsmtpd = Qpsmtpd::TcpServer->new();
$qpsmtpd->start_connection
(
local_ip => $ENV{TCPLOCALIP},
@@ -188,7 +187,7 @@ sub log {
my ($level,$message) = @_;
- $plugin_loader->log($level,$message);
+ $qpsmtpd->log($level,$message);
}__END__
i.e. eliminate the TcpServer object creation inside the child and change $plugin_loader to be the $qpsmtpd object.
We just need to make sure the parent-process object doesn't leak or grow unnecessarily.
I don't see how that should be a problem. The parent TcpServer object doesn't yet contain a connection or transaction object, only the plugins themselves. Only after the fork does any of the session-specific stuff get filled in. And you've just told me that the child process cannot affect data in the parent process with fork... ;-)
I don't like either names. 'process' seems to streamy.. and
spawn.. well.. that's got a negative connotation.
I didn't like the names either.
I think the right
direction probably had to do with talking about the smtp connection.
pre-connection and post-connection.
If I hear no objections, I'm going to go with pre-/post-connection then, since that seems to be the most accurate with the least amount of implementation leakage.
Although, really in the forkserver we might want:
pre-fork in parent post-fork in child ... run child ... before-ending in child child-cleanup in parent
Except that post-fork == connect and before-ending == disconnect in the child. Although, I found disconnect to be annoying when developing the adaptive logging plugin because disconnect fires after the transaction has gone out of scope, so I had to bind to reset_transaction instead (which just seemed wrong to me).
John
p.s. No, I can't sleep... :-(
