Hi,

I want to create a multi-threaded SMTP server. I'm using
Net::SMTP::Server as a base and thought it would be fairly
trivial to make a multi-threaded server that would spawn
threads for each incoming connection.

Initially I used (please forgive any inaccuracies, i'm
typing code from memory) ;

-----------------------------------------------------
my $server = new Net::SMTP::Server( 'localhost', '25' );

while ( my $conn = $server->accept() )
{
    my $thr = new threads( \&HandleConnection );
    $thr->detach;
}

sub HandleConnection
{
    my $conn = shift;
    <code to handle connection>
}
-----------------------------------------------------

This worked okay. But since the HandleConnection doesn't
actually do anything intensive (accepts email and stores
it as a file) and, I read, that there's quite an overhead
in creating threads, that perhaps this wasn't the optimum
way of doing it (ie time to create thread is large
comparative to thread life time).

I thought of changing it such that 10 threads would be
created immediately, and then these threads would then
handle the connections as they came in.

The problem I have had, is once the thread is created,
I cannot *seem* to pass the $conn object.

I tried using threads::shared, I also tried using
Thread::Queue, but both fail with the same error,
something along the lines of 'Invalid value assigned
to shared scalar'.

It's basically complaining that I cannot assign this
object instance to a scalar. When I use numbers on
the shared scalar, or enqueue, dequeue numbers on
the Queue it's no problem (just like the examples :).

It doesn't seem to like sharing anything but simple
data (I am hoping i'm wrong here. btw the docs only
show simple data being shared).

At this point, I started trying anything :), and the
solution that seems to work, looks like it shouldn't.

What I did was :

-----------------------------------------------------

my $server = new Net::SMTP::Server( 'localhost', '25' );

foreach  (1..10)
{
    my $thr = new threads ( \&ClientWorker, $server );
    $thr->detach;
}

sub ClientWorker
{
    my $server = shift;
    while (my $conn = $server->accept())
    {
        HandleConnection( $conn );
    }
}

sub HandleConnection
{
    my $conn = shift;
    <code to handle connection>
}
-----------------------------------------------------

So basically all 10 threads are waiting to accept a
connection on the socket. I think it's okay, because
I basically wrote an email spammer and ran it in 3
separate shells to bombard it with connections.

It doesn't look like it should work because there's no
locking/blocking on $server.

Questions :

1) How can I pass an object to a thread (AFTER it
     has been created).
2) Is my last code implementation flawed

Regards

Nick


Reply via email to