Page 1 of 2

dll question?

Posted: Fri Jan 12, 2007 2:51 pm
by srod
Hi,

the current app I'm working on involves the creation of a dll.

In itself this is fine and it is running well.

However, when compiling for threadsafe the dll gets hooked up with the debugger for some reason and nothing actually gets executed! (Switching the debugger off rectifies the problem.)

However, am I correct in saying thet a PB dll (which doesn't create any threads) is, by virtue of it being completely linked and having it's own memory, threadsafe by default? Meaning that I needn't compile with the threadsafe switch?

It certainly seems to work okay when compiled without the thdsafe switch and called by an application compiled with the thdsafe switch.

Thought I'd check though before taking this as a 'rule'. Remember that the dll in question creates no threads itself.

Thanks for any input.

Posted: Fri Jan 12, 2007 6:53 pm
by netmaestro
You are correct (and your bellybutton is showing.) It's a separate program. If it has no threads of its own, threadsafe shouldn't be an issue for it at all come compile time.

Posted: Fri Jan 12, 2007 7:27 pm
by Trond
No, he's wrong. It's not a program all of its own. If the program that has loaded the dll is threaded and calls the dll twice at the same time, bad things could happen.

Posted: Fri Jan 12, 2007 7:35 pm
by netmaestro
That situation would not be helped at all by the dll being compiled threadsafe though. If the caller has threads it has to worry about being threadsafe, not the dll. Remember the dll is not a thread of the program.

Posted: Fri Jan 12, 2007 7:44 pm
by Trond
*insert polite way of telling netmaestro that he's wrong here*

Posted: Fri Jan 12, 2007 7:57 pm
by netmaestro
le prouver, svp.

Posted: Fri Jan 12, 2007 8:10 pm
by Pupil
Trond is right. If the program that uses the dll is threaded you might have situations where different threads calls functions in the dll at the same time. This means that you'll need to keep an eye on global variables, static variables and strings as these are likely to give you problems..

Posted: Fri Jan 12, 2007 8:14 pm
by netmaestro
If the program that uses the dll is threaded you might have situations where different threads calls functions in the dll at the same time. This means that you'll need to keep an eye on global variables, static variables and strings as these are likely to give you problems..
Yes, agreed. In the calling program. Please explain how the dll being compiled threadsafe is going to help this in any way.

p.s. I think a comment from Fred or Freak would be most helpful here.

Posted: Fri Jan 12, 2007 8:17 pm
by Trond
This proves that functions in the dll runs as the thread they were called from.
DLL:

Code: Select all

ProcedureDLL ShowThreadID()
  MessageRequester("", "Message from the DLL, thread id " + Str(GetCurrentThreadId_()))
EndProcedure
EXE:

Code: Select all

Prototype ProtoVoidLong()
Global ShowThreadID.ProtoVoidLong

Procedure ThreadProc(LongVoid)
  MessageRequester("", "Message from the EXE, thread id " + Str(GetCurrentThreadId_()))
  ShowThreadID()
EndProcedure

OpenLibrary(0, "dll.dll")
ShowThreadID = GetFunction(0, "ShowThreadID")

A = CreateThread(@ThreadProc(), 0)
B = CreateThread(@ThreadProc(), 0)

WaitThread(A)
WaitThread(B)
Of course, this means that if two threads calls the same function at the same time, there will be a problem with all shared data (including PB's internal string data) in the dll. If you don't believe it, here's proof (crashes because of the PB string functions which are not thread-safe):

DLL:

Code: Select all

ProcedureDLL ShowThreadID()
  Protected Test.s
  While Len(Test) < 10000
    For i = 0 To 100
      Test = Test + "a"
    Next
    Delay(1)
  Wend
EndProcedure
EXE:
Same as above, but remove the messagerequester.
Please explain how the dll being compiled threadsafe is going to help this in any way.
Compile the dll as NOT threadsafe and it will crash. Compile it as threadsafe and it won't.

Posted: Fri Jan 12, 2007 8:19 pm
by Trond
Yes, agreed. In the calling program.
When the dll is loaded there is no difference between the dll and the "calling program". It's all code. That's sort of the point of dlls.

Posted: Fri Jan 12, 2007 8:20 pm
by Pupil
netmaestro wrote:
If the program that uses the dll is threaded you might have situations where different threads calls functions in the dll at the same time. This means that you'll need to keep an eye on global variables, static variables and strings as these are likely to give you problems..
Yes, agreed. In the calling program. Please explain how the dll being compiled threadsafe is going to help this in any way.
It's possible that it wont help, i'm not really familiar what PB exactly do different when threadsafe is on. Probably PB uses different string buffers for each thread etc, but depending on how this is implemented it might work or not work.. The only ones really qualified to answer this is probably Fred or Freak..

Posted: Fri Jan 12, 2007 8:49 pm
by netmaestro
@Trond: The presence or absence of an invalid memory access isn't relevant. You're making an example which is set up to fail, and in that case an IMA is the desired result and hiding it isn't a solution to anything. Let's wait on Fred or Freak to comment.

Posted: Fri Jan 12, 2007 9:33 pm
by Trond
No, there is absolutely nothing wrong with the example, and the invalid memory isn't "hidden", it just doesn't occur because when the dll is compiled with threadsafe it uses the threadsafe string functions.

If the regular string functions are called at the same time they will give an invalid memory access. Which is why I put the loops there, they make the regular string functions be called twice at the same time every time the program is run. Without the loop and with only a simple string manipulation the crashes would be sporadic.

Compile this similar program:

Code: Select all

Procedure ShowThreadID(LongVoid)
  Protected Test.s
  While Len(Test) < 10000
    Test = Test + "a"
  Wend
EndProcedure

A = CreateThread(@ShowThreadID(), 0)
B = CreateThread(@ShowThreadID(), 0)

WaitThread(A)
WaitThread(B)
If it's compiled with threadsafe it doesn't crash else it crashes. This also shows that it doesn't matter if the code is in a dll or not.

Posted: Fri Jan 12, 2007 9:48 pm
by netmaestro
This also shows that it doesn't matter if the code is in a dll or not
Exactly, which proves that the coding error is in the calling program. Look in the PB docs at the example provided for the CreateMutex command. This shows the correct way to code a thread when you're doing what your example does. With the caller coded properly, there is no error regardless of whether the dll is compiled threadsafe or not. At the risk of repeating myself, I suggest we wait on a comment from Fred or Freak.

Posted: Fri Jan 12, 2007 9:51 pm
by Trond
At the risk of repeating myself, the code is correct if threadsafe is enabled. Mutexes are for manual syncronization of things in the program or programs that are compiled without threadsafe. You don't need a mutex to do a simple string manipulation when you compile as threadsafe, that's the POINT of threadsafe.

If you think the code is incorrect, point out where the error is.