473,473 Members | 1,857 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

problems with threaded socket app

I've been working on a threaded daemon application to filter email. The
source for the program is here:

http://phantom.dragonsdawn.net/~gord...-pythonfilter/

The daemon loads individual filters as modules and hands the names of the
message and control files to each module in turn for processing. One of
the modules (filters/dialback.py) checks the address of the sender,
connects to the MX servers for the senders domain, and validates that the
sender address is valid. In order to implement a timeout on the dialback,
each message is processed by two threads. The first thread creates an
SMTP object and then starts a second thread to do the lookup using that
SMTP object. If the lookup takes too long, the first thread closes the
SMTP object's socket and collects the failure from the second thread.

During testing, that all works fine. However, in real world use, the
program eventually deadlocks. When it does so, there are several dialback
threads in process, and the first of each pair seems to be reading from
the status pipe. I cannot connect a debugger to the second of the pair to
see what state it's in.

I'm running this application on python2-2.2.2-11.7.3 under Red Hat Linux
7.3.

Does anyone have any suggestions for where I can start looking for the
problem?

Jul 18 '05 #1
2 1882
"Gordon Messmer" <go****@dragonsdawn.net> wrote in message
news:pa****************************@dragonsdawn.ne t...
I've been working on a threaded daemon application to filter email. The
source for the program is here:

http://phantom.dragonsdawn.net/~gord...-pythonfilter/
The daemon loads individual filters as modules and hands the names of the
message and control files to each module in turn for processing. One of
the modules (filters/dialback.py) checks the address of the sender,
connects to the MX servers for the senders domain, and validates that the
sender address is valid. In order to implement a timeout on the dialback,
each message is processed by two threads. The first thread creates an
SMTP object and then starts a second thread to do the lookup using that
SMTP object. If the lookup takes too long, the first thread closes the
SMTP object's socket and collects the failure from the second thread.

During testing, that all works fine. However, in real world use, the
program eventually deadlocks. When it does so, there are several dialback
threads in process, and the first of each pair seems to be reading from
the status pipe. I cannot connect a debugger to the second of the pair to
see what state it's in.

I'm running this application on python2-2.2.2-11.7.3 under Red Hat Linux
7.3.

Does anyone have any suggestions for where I can start looking for the
problem?


if rpipe not in ready_pipes[0]:
# Time to cancel this SMTP conversation
smtpi.close()
# The dialback thread will now write a failure message to
# its status pipe, and we'll need to clear that out.
os.read( rpipe, 1024 )
continue

The code creates a "race" condition. To work correctly it requires the
worker thread to raise and handle an exception, and to write that result
onto the pipe BEFORE your main thread attempts to read the pipe.

If the worker thread loses the race, the next MX result you process will
recieve the last MX's results 400 error code, and your left with 1 thread at
the end of the sequence which can't terminate as it stays active until what
its written to the pipe is read from the pipe.

Simple enough to fix, just add a select call between closing the SMTP
connection and reading the expected 400 error response.

Anthony McDonald
Jul 18 '05 #2
On Mon, 15 Sep 2003 09:58:50 +0200, Anthony McDonald wrote:

if rpipe not in ready_pipes[0]:
# Time to cancel this SMTP conversation
smtpi.close()
# The dialback thread will now write a failure message to
# its status pipe, and we'll need to clear that out.
os.read( rpipe, 1024 )
continue

The code creates a "race" condition. To work correctly it requires the
worker thread to raise and handle an exception, and to write that result
onto the pipe BEFORE your main thread attempts to read the pipe.

If the worker thread loses the race, the next MX result you process will
recieve the last MX's results 400 error code, and your left with 1 thread at
the end of the sequence which can't terminate as it stays active until what
its written to the pipe is read from the pipe.

Simple enough to fix, just add a select call between closing the SMTP
connection and reading the expected 400 error response.

I can do that, but can you explain why, if the monitor thread loses the
race, it wouldn't block until the worker thread writes its status to the
pipe?

The code below should have the same race condition, but it works properly.

[root@deerhunter root]# python2
Python 2.2.2 (#1, Jan 30 2003, 21:26:22)
[GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import os
import thread
import time
def write_stat( wpipe ): .... time.sleep(20)
.... os.write( wpipe, 'my status' )
.... (rpipe, wpipe) = os.pipe()
thread.start_new_thread( write_stat, (wpipe,) ) 1026 test = os.read( rpipe, 1024)
print test my status


Jul 18 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Hameed Khan | last post by:
hi all, i am getting some problems with my first socket script. can any one of you point me why this is happening. the server script suppose to accept one connection at a time and send countdown...
1
by: Tim Black | last post by:
My application requires sending a large piece (~2MB) of data to several devices on a network via TCP sockets. I have experimented with different methods for doing this and this has raised some...
5
by: Parahat Melayev | last post by:
I am trying to writa a multi-client & multi-threaded TCP server. There is a thread pool. Each thread in the pool will handle requests of multiple clients. But here I have a problem. I find a...
1
by: Jim P. | last post by:
I'm having trouble returning an object from an AsyncCallback called inside a threaded infinite loop. I'm working on a Peer2Peer app that uses an AsyncCallback to rerieve the data from the remote...
2
by: WTH | last post by:
with a C# client (and/or server, but server not important)? I've got a scalable high speed (uses completion ports) C++ TCP/IP communication server but I'd like to write a C# client that other C#...
0
by: ZR | last post by:
I am writing two applications which needs to (among other things) communicate through network, so one of them is a client and the other one is a server. I have used asynchronous socket examples...
11
by: Steve Smith | last post by:
I have written a winforms application that launches approximately 150 threads with Thread.ThreadStart() Each thread uses CDO 1.21 to logon to a different Exchange mailbox and send/receive a...
4
by: shofu_au | last post by:
Hi Group, A question about threads and asynchronous TCP sockets. In the attached code, even if the host TCP server is not running my code reports that the connection has been established. ...
2
by: kodart | last post by:
Introduction Performance is the main concern to most server application developers. That’s why many of them anticipate using .NET platform to develop high performance server application regardless...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.