Memory leak in Fax Service Extended

G

Guest

Hi all,

We have a service that polls the Fax Service sent items folder. Recently we
have had reports of the service leaking memory. I have been unable to find
any references to this problem on the web.

The problem was originally noticed in a Delphi application, but reproduces
in managed code too. Some C# to illustrate the problem is below. Varying the
value of the parameter to GetMessages doesn't seem to make a difference, and
explicitly setting the iterator variable to null after the while loop doesn't
seem to help either.

We're running on a fully patched Windows XP Pro SP2.

using FAXCOMEXLib; // requires a reference to c:\windows\system32\fxscomex.dll
class Program {
static void Main(string[] args) {
FaxServer faxServer = new FaxServerClass();
while (true) {
IFaxOutgoingMessageIterator iterator =
faxServer.Folders.OutgoingArchive.GetMessages(100);
try {
iterator.MoveFirst();
while (!iterator.AtEOF) {
IFaxOutgoingMessage message = iterator.Message;
iterator.MoveNext();
}
} catch {
// squish
}
}
}
}
 
G

Guest

Hi there, Gavin!

I have found this to be the iterator problem. It manifests itself when you
walk past the boundary. Unfortunately, with the iterator you get with
IFaxOutgoingArchive::GetMessages() it is not obvious (probably possible,
though I have not figured it out) how to keep within the boundary. If you'd
known the number of items in the archive, then simply rewriting the loop like:
iter->MoveFirst();
for(numItems=?;numItems < maxItems-1; iter->MoveNext() )
{
//iter->Message;
}
would do the trick.
Probably, AtEOF evaluates the end-of-file condition one position too late.
Which, if placed inside a loop, will produce leaks proportional to the size
of the archive queue X number of iterations.
One way you could tackle this problem is finding out how many items the
archive contains and building your iteration upon this finding instead of
relying on AtEOF.
For example, query archive folder with IFaxOutgoingArchive::ArchiveFolder()
and iterate through .TIFs there, then and base your iterations on that
count.

Hope that helps,
dmitri.
 
G

Guest

Hi Dmitri,

Thanks for your response.

Your suggested implementation didn't work for me - it actually looks like
the leak is coming from the call to the iterator's MoveNext() method.
However, your comments about looking in the filesystem have given me a
solution.

I can extract the message ID from the filename - it's the bit after the '$'
- and then ask the IFaxOutgoingArchive for the individual message using the
ID. This does not produce the leak.

Thanks for your help!
 
G

Guest

Hello there, Gavin!

Yes, the code example I gave last time was inadequate to say the least. But
i've been able to rely just on the number of files in the archive directory
to walk through the IFaxOutgoingArchiveIterator w/o leaks:

archive->Refresh();
int msgCount = retrieve_num_files_in_archive_dir();
if( msgCount > 0 )
{
iter->MoveFirst();
//extract info from the first message, i.e. use iter->Message
//iterate through the rest of the messages
for( int k = 1; k < msgCount; ++k )
{
iter->MoveNext();
//extract info from the this message, i.e. use iter->Message
}
}

That should've worked for you too o;)
But i'm glad you came up with a solution,
g'd day,
dmitri.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top