No announcement yet.

PB DLL Internet wrapper

  • Filter
  • Time
  • Show
Clear All
new posts

  • PB DLL Internet wrapper

    Does anybody have expertice on getting a PB DLL connected to the internet?

    I'm getting stuck here: I wrote a simple VB ActiveX which calls the PBDLL. It works just fine as long as you keep it to single threaded.
    As soon as I compiled it in apartment threaded mode the CPU time of IIS just through the roof and crashes hard.

    I already rewrote my DLL to be thread safe, that is: all variables local with one time internal threading where I pass my data from the sub that creates the threads (2 actually) using CoTaskMemAlloc. So it should be thread-safe.
    I already tested it like this: a VB app uses the DLL and provides a series of imputs, expecting output. If I run the test with 2 applications, they don't interfere with oneanother. So it seems fine.

    Anybody got any ideas what I'm doing wrong / have to do, to get it work from a ASP webpage using CreateObject, call function (in ActiveX).

    Hope someone can help



  • #2
    VB is not know to thread well, I would strongly suspect that is where your problem lies..

    mailto:[email protected][email protected]</A>
    Scott Turchin
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi


    • #3
      Hi Jeroen,

      I've got some experience with what you're trying to do. There's
      been several times where I've had to wrap a VB ActiveX Dll around
      my PBDll dll's specifically for use on an IIS server. I've had
      very good luck using this method, so don't think you're going
      down the wrong path.

      Anyway.... Just some thoughts...

      Have you tried creating an apartment threaded VB dll that doesn't
      call the PB Dll? Just put some simple function in the VB Dll
      that returns something.... See how IIS responds to that?

      I must say that none of the PB Dll's that I've created for the
      web have had any internal threading going on so I can't help you
      there. Is the internal threading in the PB Dll absolutely necessary?

      Also, have you tried creating a simple function (something without
      internal threading but is thread safe) in your PB Dll that your
      VB ActiveX Dll calls? How does it react when run under load on
      your IIS box?

      One more thing. I'm not sure what your PB Dll is doing but is there
      something that it's trying to access on the web server machine that it might
      not have permission too access? The IIS web server web(s) (by default) run
      as NT user(s) that have very little privileges on the web server machine

      That's all I can think of for now, but if I think of anything else
      I'll post again.


      Scott Wolfington

      [This message has been edited by Scott Wolfington (edited March 05, 2003).]
      Scott Wolfington


      • #4
        Thanks Scott,
        Your answer suggested I was doing everything right except the threading. So I left that out and it worked just great.
        So at least I narrowed the problem down:

        My testing shows that it's not the threading with the CoTaskMemAlloc function. That works just OK.
        Yet, as soon as I add SQL Threads it starts going wrong. That is: just doing %THREAD_START, 1 and stopping it works fine. But as soon as I also add a real SQL statement to execute, it goes wrong.

        I'm having 2 threads. I've set the %THREAD_MAX to 20. I've used seperate DB numbers for each of the two threads (1 and 2) and used fixed statement numbers for each thread as well (4 and 5).
        If I test this in a multi-user test from a webpage passing the request to the DLL, IIS crashes!

        I'm using the function according to the manual (I believe) and I'm not deleting or altering any table or database (so no cach problems). It's just reading them.

        The simplified code looks like this:
        ' DB1 and 2 are opened. The initionalize also had
        'result& = SQL_Initialize(3, 256, 240, 256, 3, 1, 0, 0)
        'result& = SQL_THREAD(%THREAD_MAX, 50) 
        ' pass info to ThreadInfo
        DIM ThrInf AS ThreadInfo PTR     ' UDT for all necessary info in threads
        ThrInf = CoTaskMemAlloc(SIZEOF(@ThrInf))
        IF ThrInf THEN
            @ThrInf.Var1 = Internal.Var1    ' UDT for local internally passed info 
            @ThrInfo.Var2 = Session.Var2    ' UDT for local internally passed info 
            ' for all vars
            @ThrInfo.SQLHit1 = 0    
        end if
        ' this example uses only 1 thread (for testing)
        THREAD CREATE MyThread1(ThrInf) TO hThread1
        ' the thread changes the value: ThrInf.SQLHit1 and (if success: has a result stored in .recnr2)
        DO WHILE @ThrInf.SQLHIT1 = 0
            SLEEP 1
        IF @ThrInf.SQLHit1 = 3 THEN
            Internal.SQLHit1 = 3
            Internal.recnr = @ThrInf.recnr2 ' pass result from Thread to Internal info
        ELSEIF @ThrInf.SQLHit1 = 4 THEN
            Internal.SQLHit1 = 4
        END IF                  
        ' to be safe: cancel the statement
        ' close thread
        THREAD CLOSE hThread1 TO hResult
        ' free memory
        CoTaskMemFree ThrInf
        ' done
        FUNCTION MyThread1(ThrInf AS ThreadInfo PTR) AS LONG
        result& = SQL_THREAD(%THREAD_START, 1)
        LOCAL Thread1 AS ThreadInfo
        Thread1.Var1 = @ThrInf.Var1
        ' etc.
        local SQLST as STRING, result&, StmtNr2 as double, Cols as double
        StmtNr2 = 5
        SQLST = "Select * from Table1"
        result& = SQL_STATEMENT(1, StmtNr2, %IMMEDIATE, SQLST)
        IF (result& <> %SUCCESS AND result& <> %SUCCESS_WITH_INFO) OR  SQL_ResultColumnCount(1, StmtNr2) = 0 THEN
          ' report action
            Cols = SQL_ResultColumnCount(1, StmtNr2)
            SQL_Fetchresult 1, StmtNr2, %FIRST_ROW
            ' more code to handle the results, as well as continued action / Sql statements (using the same db and stmt nr.)
        END IF
        result& = SQL_THREAD(%THREAD_STOP, 1)
        end function

        Anybody got some ideas what I'm doing wrong?



        [This message has been edited by jeroen brouwers (edited January 22, 2001).]