dll question?

Everything else that doesn't fall into one of the other PB categories.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

dll question?

Post 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.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

*insert polite way of telling netmaestro that he's wrong here*
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

le prouver, svp.
BERESHEIT
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post 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..
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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.
Last edited by Trond on Fri Jan 12, 2007 8:21 pm, edited 1 time in total.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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.
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post 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..
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post 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.
BERESHEIT
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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.
Post Reply