Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28445 Discussions

CVF 6.6 DLL being called by Delphi ISAPI App Problem

iwatkins
Novice
2,099 Views
Hi All,

Have a quite large program in Fortran that I've converted to a DLL. It takes a bit of time to run (~ 20 secs) and need to be run via a web page.

OK, I have written a Delphi ISAPI DLL that calls this CVF DLL passing it a few startup parameters.

The Delphi DLL can be called by multiple users via the webserver (IIS 5.0).

Now, I assumed that the ISAPI DLL runs each time in its own thread on IIS. I kind of assumed that the called CVF DLL would also have an area to itself.

However, if you call the application twice at the same time, data within the CVF DLL is corrupted/overwritten by the second call if it occurs at the same time.

I.e. call 1 and call 2 both send their startup parameters correctly and on both occasions the CVF DLL recieves them fine (proved that).

However, large data arrays within the CVF DLL are overwritten by data from the 2nd call while the 1st call is progressing.

I've tried using the Multi-Thread Library, but that doesn't seem to help at all.

I need some pointers as for what to look at. Or clues how to force a calling program to use a 'new' copy of the CVF DLL.

Cheers

Ian
4 Replies
Jugoslav_Dujic
Valued Contributor II
2,099 Views
The problem is that by default all variables are SAVEd (static) in CVF; that implies that subroutines are not reentrant. To allow reentrancy, all variables have to be either automatic (stack) or allocatable.

Thus, *ALL* routines have to have RECURSIVE attribute. You can achieve the same effect (without adding it to code) by compiling with "Enable recursive routines" or "Variables default to AUTOMATIC" switch (/automatic)(they mean the same IIRC).

But that's not all -- reentrancy means no COMMONs and no changeable global data at all (the latter can be workarounded but I wouldn't go into detail). Further, take care of a gotcha in Fortran standard -- a variable automatically gets SAVEd when initialized via DATA or initialization statement, i.e.:
RECURSIVE SUBROUTINE foo()
INTEGER:: i = 0  !i is now SAVEd regardless of RECURSIVE
INTEGER:: i
i = 0            !This is fine, i is AUTOMATIC.

There's also AUTOMATIC keyword in CVF, but it's non-standard.

HTH
Jugoslav
0 Kudos
Steven_L_Intel1
Employee
2,099 Views
I suspect that the problem is caused by the DLL being loaded once and multiple threads calling the routines. If there were separate processes calling the DLL, then the reentrancy issue wouldn't matter.

Jugoslav has the correct solution - declare all the routines RECURSIVE or use the compiler option. Note that simply declaring individual variables as AUTOMATIC may not be sufficient because the compiler may still use static storage for temporary values.

Steve
0 Kudos
iwatkins
Novice
2,099 Views
Thank you both,

I think I'll just sit down and have a play with this outside of the web environment first, much easy to debug.

I've checked also with the Delphi groups and with the IIS groups and they concur that each ISAPI DLL gets its own thread for execution but any external DLLs etc. are run in a single, shared thread. Which I kind of knew anyway :(

By the way, I tend to do more of the Delphi/web stuff nowadays and leave the main Fortran development to the scientists in the team. You should have seen their faces when I told them no more COMMON blocks (which I've been saying for years) and that they will probably have to change all their code :-))

Thanks again.

Ian
0 Kudos
Steven_L_Intel1
Employee
2,099 Views
This is indeed going to be a big shock to your Fortran programmers - no global state (no COMMON, no module variables). Rather than using COMMON, they'll have to use local variables (could be ALLOCATABLE) that get passed as arguments. Also, the DLL should be built with the "multithreaded" option selected (and linked against the thread-safe run-time DLLs - these are options under Libraries.)

The Programmer's Guide has some guidance on writing multithreaded applications, though they can skip the part about creating and synchronizing threads.

Steve
0 Kudos
Reply