Announcement

Collapse
No announcement yet.

Multi-thread in VB6 source code comments

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • John Petty
    replied
    Thomas
    Good point but remember the dates of the posts. Back then creating a COM server with PB was extremely difficult so the issue you raise wasn't considered.

    Leave a comment:


  • Michael Mattias
    replied
    >COM ERRORS ARE NOT THREAD SAFE

    Given that is true...

    Can't you avoid that by initializing COM on a separate thread of execution and executing "possibly conflicting COM operations" there?

    Maybe someone who knows COM way better than do I can answer that.

    The re-entrant thing, PB code always supports re-entrant execution; which does NOT mean you can forget about it and do things your own way without considering what happens when you take advantage of this feature.

    Just FWIW, CONTROL SET TEXT and SendMessage(hwnd_on_this_thread) both require re-entrant execution. (Hmm, so you were doing re-entrant applications and didn't even know it, huh?)

    MCM

    Leave a comment:


  • Thomas Tierney
    replied
    Hey! this thing popped up again? its been a while since I commented or saw this thread...

    John,
    Simply put VB6 is not re-entrant, this means that you can do whatever you want, when ever you want but the main problem is...

    COM ERRORS ARE NOT THREAD SAFE

    This is the issue when dealing with multi-threaded VB6 apps... if you can get past that then it is thread safe...

    So, if your VB6 App decides there is a COM error and your PB dll also decides there is a com error then the COM ERROR Stack will be smashed with two competing errors...

    if you can avoid COM errors then your application will live happy and bee happy....

    But the moment you have a COM error then good luck. There are two ways to avoid this... 1. only use api's that don't issue com errors... or 2. hack the assembly output from the C1 compiler before the C2 compiler gets a hold of it..in a way that makes the COM ERROR stack multi-threaded.

    There used to be a doc on that somewhere, don't recall where - don't really care these days either...

    Again, if none of this applies to you.... don't look into it any further... just my two cents

    TTFN!

    Leave a comment:


  • Michael Mattias
    replied
    > VB6 will not know when it is okay to end.

    Your VB program can ...

    WaitForMultipleObjects (array of thread handles created in your DLL).

    That WILL hang the VB UI unless you do something cool, as "Wait For" means WAIT.

    I'd probably use (hell,I have used) the MsgWaitForMultipleObjects() function in my message loop to "wait for all my worker threads to complete but keep my UI alive so I don't get that dopey white rectangle" but as I recall, VB6 does not provide the programmer access to the message loop. So I don't know what I would do here, except maybe try to sell an upgrade to the UI itself.

    MCM

    Leave a comment:


  • Mike Doty
    replied
    Note:
    I believe extra threads are reported that way and the thread count may never reach 1. VB6 will not know when it is okay to end.

    Leave a comment:


  • Michael Mattias
    replied
    THis function here..
    Code:
    FUNCTION PBTHREADCOUNT EXPORT AS LONG
      FUNCTION = THREADCOUNT
    END FUNCTION
    .. is not really accurate, because of what the PB THREADCOUNT() function is counting.

    Here's some code which counts actual thread OBJECTs and will include threads created in other code modules:

    Real Thread Count for this process
    FULL BBS thread:
    RealThreadCount:Full Thread

    MCM

    Leave a comment:


  • Mike Doty
    replied
    Update PbThreadClose to also update gHandle array in a critical section.
    Code:
    FUNCTION PBTHREADCLOSE(ElementNumber AS LONG) EXPORT AS LONG
      EnterCritical
      LOCAL result AS LONG
      THREAD CLOSE gHandle(ElementNumber) TO result   '0 = failure
      IF result THEN
        gHandle(ElementNumber) = 0 'make slot available
        FUNCTION = result
      END IF
      LeaveCritical
    END FUNCTION

    Leave a comment:


  • John Petty
    replied
    I agree with Mike Thomas you will note that the callback in my method is never called in a rentrant way, quote two different ways to to ensure that.
    The first obvious reason your simple statement is wrong is that VB6 can be used as a COM server and thus be called by many programs at the same time. The COM engine does the neccessary marshelling to avoid the problem you quote. You will find many methods on the net including from MS staff of how to make VB6 multi-threaded. As you say triggering an event is one of them, no real hack needed or COM, it can be done by simply sending a Windows message to an esisting control that understands it, I have seen Key_Down used for that purpose with VB to VB, the callback correctly done is simpler.

    Leave a comment:


  • Mike Doty
    replied
    I have never GPF'ed.
    I call other PB routines from the thread.

    Leave a comment:


  • Thomas Tierney
    replied
    vb 6 is not reentrant. any threaded dll you create will cause a gpf one way or another. There is a hack I put together that is the only real solution to the problem unless of course pb builds in the ability to trigger an internal event from outside the class.

    Leave a comment:


  • John Petty
    replied
    Mike and Peter
    It is actually quite simple, but please don't confuse the word CallBack with Windows messages or GUI, it is just a function that you can call with CALL DWORD in PB and actually there is no difference if the DLL is being used in a PB program or in fact if the whole thing is a single exe, You just need to establish the functions address. In VB6 you do it like this in a module (not a form) you create the callback function
    Public Function MyDLLCallBack(Data1 as, Data2 as, etc etc) as Long of course the actual name is irrelevant.
    Before doing anything else with the DLL you would initialise it like
    er = InitMyDLL(AddressOf MyDLLCallBack, any other useful settings)

    In my last post I suggested that threads reported to a single non-exported funtion but its not always needed but was one suggestion for queueing the data going back to VB6 in case the callback is not truely re-entrant and two threads could send data at about the same time. Actually each thread can report back directly with a single global flag protected by a mutex. Any thread sending data would first check the flag to see if the receiving program was ready to receive data if so it first sets the flag to False and sends the data. The receiving program after it has finished with the data simply calls an exported funtion like ICanNowAcceptData to set the flag back to True.
    Of course the call from PB and any thread is a standard CALL DWORD to the saved address. If you have threads doing vastly different things then you can have multiple callbacks.
    Common sense is needed, as VB6 itself is not thread safe you don't pass or use Windows handles or any other addresses from it other than the callback address.
    John

    Leave a comment:


  • Mike Doty
    replied
    Sounds great.
    Enhance or replace my code at anytime!

    I'd work on it now, but caught up in adding PDF support.
    Thanks to MM for mentioning haru and Jose Roca for headers, demo and more.

    You guys are way ahead of me in the CALLBACK area. I've only
    used threads for transmitting/receiving files, allowing buttons and menus
    to react without waiting and splash screens. This is probably why I haven't had any problem.
    I will soon attempt updating an ActiveX grid control for VB6 from a thread.
    I certainly would like to add more to this threading DLL.
    All other tested code goes into another DLL and is also callable by VB6.
    I can also compile PowerBASIC code from a network terminal giving me two monitors.

    This is the best of two worlds.
    PowerBASIC on one monitor and VB6 environment on the other monitor working together.
    Last edited by Mike Doty; 11 Oct 2009, 11:23 AM.

    Leave a comment:


  • John Petty
    replied
    Actually SP2 of VB5 was thread safe but they messed it up again in VB6 that does not mean it can't be done. Results from individual threads can be passed back to a single non exported function say by sending a message to a hidden dialog which causes it to read a synchronised global (i.e. with a mutex), that function can then forward the information or results to a custom written callback in the VB6 program, alternatively you could trigger an event in VB6 which causes it to interogate the DLL for results but that is messier.

    Leave a comment:


  • Peter Redei
    replied
    Mike,

    I have not tried your code.
    In the past I spent quite a time to try to do the same. VB6 is not thread safe, period. You may succeed with a multithreaded PB DLL when you use working threads that do not return any value to VB6. When I needed to return value the only working solution I found was to create a textbox in VB6, pass the handle of the textbox to the PB DLL and write the value in the PB DLL to the textbox. Than I used the Textbox_Change event to get the value in VB6 and clear the textbox. I also found that the exact same solution might appear runnning safely from one VB6 application but not from another depending on the controls and components the VB6 program uses.

    Peter Redei

    Leave a comment:


  • Mike Doty
    replied
    I have been informed this may be unstable.
    If you know of a way to brute force test this, please let me know.
    I've been doing this for a couple of years without any problems.
    I think some of the other solutions were unstable.

    Leave a comment:


  • Mike Doty
    started a topic Multi-thread in VB6 source code comments

    Multi-thread in VB6 source code comments

    Comments on multi-threading using VB6 in source code forum.
    Add multi-threading to VB6. It works in or outside the VB6 environment.
    Try ending the VB6 program while threading.

    Multi-threaded PB code with a VB6 front-end.

    http://www.powerbasic.com/support/pb...ad.php?t=41675
    Last edited by Mike Doty; 10 Oct 2009, 11:14 AM.
Working...
X