Login  
Search All Forums
Dart Home | PowerTCP Web for ActiveX | Custom Development Reply | PowerTCP Web for ActiveX Topics | Forums   
AuthorForum: PowerTCP Web for ActiveX
Topic: Non-blocking http post crashing
su27k

From: L.A,, CA USA
Posts: 4
Member Since: 01/08/04
posted January 8, 2004 7:02 AM

Why does the following code keeps crashing?
------------------------------------------
Option Explicit
Private m_bytRequestData(0 To 0) As Byte
Private m_bytResponseData() As Byte
Private m_objResponseHeader As DartStrings
Private m_objRequestHeader As DartStrings
Private m_strStates As String

Private Sub Command1_Click()
  Unload Me
End Sub

Private Sub Form_Activate()
  Call SendRequest
  m_strStates = m_strStates & "Form activate finished" & vbCrLf
End Sub

Private Sub SendRequest()
Dim header As DartStrings '<-- THIS IS TROUBLE!!!

  Set m_objRequestHeader = New DartStrings
  m_objRequestHeader.Add "Content-Length: 0" & vbCrLf
  Http1.Url = "http://www.microsoft.com"
  Http1.Timeout = 0
  Http1.Post m_bytRequestData, m_objRequestHeader, m_bytResponseData, m_objResponseHeader
  m_strStates = m_strStates & "Post finished" & vbCrLf
End Sub

Private Sub Http1_Error(ByVal Number As DartWebCtl.ErrorConstants, ByVal Description As String)
  m_strStates = m_strStates & "Error: Number=" & Number & ", Description=" & Description & vbCrLf
End Sub

Private Sub Http1_Progress(ByVal Count As Long, ByVal Size As Long)
  m_strStates = m_strStates & "Progress: Count=" & Count & ", Size=" & Size & vbCrLf
End Sub

Private Sub Http1_State()
  m_strStates = m_strStates & "State: State=" & Http1.State & vbCrLf
  If Http1.State = httpCompleted Then
    MsgBox "States: " & vbCrLf & m_strStates
  End If
End Sub
----------------------------------------
My setup: Windows 2000 Pro SP4, VB6 SP5, DartWeb.dll 1.1.0.1, DartSock.dll 2.2.0.20

This problem seems to be caused by the line "Dim header As DartStrings" in function SendRequest(), if it is commented out then the code runs fine. However this does not seem to make sense since this is a simple declaration.

In my production application, it does not crash so easily, but if I use the header object declared in the function in the post method, instead of the one declared in module level, then the application will crash when running under Windows 2000 Server.

I think this may be caused by web control attempting to use the dartstrings object declared in a function which is already finished. But I thought COM object are not freed unless their reference count reaches zero, since the web control maintains a reference to the dartstrings object, this should not be a problem, am I wrong?
Tony Priest



From: Utica, NY USA
Posts: 8466
Member Since: 04/11/00
posted January 8, 2004 9:06 AM

It doesn't crash for me. I don't see how it could since you are not using it anywhere anyway. Something else must be going. If you narrow it down, please let us know.
su27k

From: L.A,, CA USA
Posts: 4
Member Since: 01/08/04
posted January 8, 2004 9:42 PM

OK, second try :-)
------------------------------------------------
Option Explicit
Private m_bytRequestData(0 To 0) As Byte
Private m_bytResponseData() As Byte
Private m_objResponseHeader As DartStrings
Private m_objRequestHeader As DartStrings
Private m_strStates As String

Private Sub Command1_Click()
  Call SendRequest
  m_strStates = m_strStates & "Command1_Click finished" & vbCrLf
  Debug.Print "Command1_Click finished"
End Sub

Private Sub SendRequest()
Dim header As DartStrings '<-- this is trouble!!!

  'Set m_objRequestHeader = New DartStrings
  Set header = New DartStrings
  'm_objRequestHeader.Add "Content-Length: 0" & vbCrLf
  header.Add "Content-Length: 0" & vbCrLf
  Http1.Url = "http://www.microsoft.com"
  Http1.Timeout = 0
  'Http1.Post m_bytRequestData, m_objRequestHeader, m_bytResponseData, m_objResponseHeader
  Http1.Post m_bytRequestData, header, m_bytResponseData, m_objResponseHeader
  m_strStates = m_strStates & "Post finished" & vbCrLf
  Debug.Print "Post finished"
End Sub

Private Sub Http1_Error(ByVal Number As DartWebCtl.ErrorConstants, ByVal Description As String)
  m_strStates = m_strStates & "Error: Number=" & Number & ", Description=" & Description & vbCrLf
  Debug.Print "Error: Number=" & Number & ", Description=" & Description
End Sub

Private Sub Http1_Progress(ByVal Count As Long, ByVal Size As Long)
  m_strStates = m_strStates & "Progress: Count=" & Count & ", Size=" & Size & vbCrLf
  Debug.Print "Progress: Count=" & Count & ", Size=" & Size
End Sub

Private Sub Http1_State()
  m_strStates = m_strStates & "State: State=" & Http1.State & vbCrLf
  Debug.Print "State: State=" & Http1.State
  If Http1.State = httpCompleted Then
    MsgBox "States: " & vbCrLf & m_strStates
  End If
End Sub
-----------------------------------------------
Run this in VB IDE, click the button, it crashes everytime after "Progress: Count=1, Size=1". This is the setup I used in my production application (see the 2nd paragraph in my first post).

After you run this example and crashed, try to run my first example again, see if it crashes this time. It seems that once you crashed it by using the "header" variable, it will always crash as long as the "header" variable exists (unless of course you reboot the machine).

If this doesn't work, I don't know what to do. this thing is very hard to debug since it does not have a repeatable pattern, gives different result in Win2000Pro/Server and XP. Any advice on stablize the non-blocking mode would be very welcome :-)
Tony Priest



From: Utica, NY USA
Posts: 8466
Member Since: 04/11/00
posted January 8, 2004 10:45 PM

You are accessing m_strStates outside of the events while it is being access in the events. You see where you access it immediately after the Post? That line of code will be executed immediately after Post returns. Since you choose to use asynchronous mode Post returns immediately (it doesn't block)

If you remove the the lines that access m_strStates immediately after the Post and immediately after the call to SendRequest, the crash will go away.

If you want to update status after the operation is complete, you should put the code in the event.

Is there some reason you are choosing to use non-blocking mode? It's much easier to use blocking mode. You might want to consider switching if you continue to problems.

su27k

From: L.A,, CA USA
Posts: 4
Member Since: 01/08/04
posted January 10, 2004 10:09 AM

Now we're getting somewhere! Thank you very much for the insight, I didn't realize that VB's string access (and other variable access?) has concurrency issues. By removing the m_strStates lines as you suggested, the code did not crash when running in IDE, with one caveat: if I try to enter something into the IDE after the code is run, the IDE crashes immediately. Anyways, this variable access rule explains alot, and now we can get to the real problem shown up in my production application.

The following code is the closest approximation to my production code after previous discussion, note I removed m_strStates altogether, since no such variable exists in my own application, I added it to the demo code just to make things interesting, without realizing it actually complicated the whole situation.
-------------------------------------------------
Option Explicit
Private m_bytRequestData(0 To 0) As Byte
Private m_bytResponseData() As Byte
Private m_objResponseHeader As DartStrings
Private m_objRequestHeader As DartStrings

Private Sub Command1_Click()
  Call SendRequest2 '<-- this line is important!
End Sub

Private Sub SendRequest1()
Dim header As DartStrings
  Set header = New DartStrings
  header.Add "Content-Length: 0" & vbCrLf
  Http1.Url = "http://www.microsoft.com"
  Http1.Timeout = 0
  Http1.Post m_bytRequestData, header, m_bytResponseData, m_objResponseHeader
End Sub

Private Sub SendRequest2()
  Set m_objRequestHeader = New DartStrings
  m_objRequestHeader.Add "Content-Length: 0" & vbCrLf
  Http1.Url = "http://www.microsoft.com"
  Http1.Timeout = 0
  Http1.Post m_bytRequestData, m_objRequestHeader, m_bytResponseData, m_objResponseHeader
End Sub

Private Sub Http1_Error(ByVal Number As DartWebCtl.ErrorConstants, ByVal Description As String)
  'Debug.Print "Error: Number=" & Number & ", Description=" & Description
End Sub

Private Sub Http1_Progress(ByVal Count As Long, ByVal Size As Long)
  'Debug.Print "Progress: Count=" & Count & ", Size=" & Size
  HScroll1.Max = 10000
  HScroll1.Value = 10000 * Count / Size
End Sub

Private Sub Http1_State()
  'Debug.Print "State: State=" & Http1.State
  If Http1.State = httpCompleted Then
    MsgBox "Completed"
  End If
End Sub
-------------------------------------------------
Note a new control HScroll1 is added to the form, this is a scroll bar. And I separated the two version of SendRequest(), one uses the local header object, one uses the form level header object.

If I use SendRequest2(), then everything runs fine, the scroll bar will display the progress of download nicely. However, if I use SendRequest1(), then it will crash, most likely after the event Http1_Progress.

Actually this code is originally written in blocking mode, and now it's being upgraded to non-blocking mode by one of my colleagues. The reason is timeout does not work with blocking mode, there seems to be a upper limit. Even if we set the value to a very large number, timeout always occurs after just a few minutes. Since the website we're connecting to could process the uploaded data for quite a while, a small timeout would not be acceptable.
Tony Priest



From: Utica, NY USA
Posts: 8466
Member Since: 04/11/00
posted January 10, 2004 10:21 AM

At this point I don't think we are talking about bugs anymore. Since you are requesting code analysis this issue will have to be taken up off of the forum. Please write up a description off the problem and send a sample project to support@dart.com.
su27k

From: L.A,, CA USA
Posts: 4
Member Since: 01/08/04
posted January 11, 2004 3:29 AM

OK, I'll try that option, although I don't quite understand the difference between talking about bugs and code analysis.
Tony Priest



From: Utica, NY USA
Posts: 8466
Member Since: 04/11/00
posted January 11, 2004 9:44 AM

The forum is for help with getting started with the product, reporting possible bugs and suggestions to aid in your development.

In your case, it was proven that the "crash" was occurring because of mis-management of global variables. I have no reason to believe that this is not the case again.

Once it gets to the point that you are posting entire programs and asking "why does it do this when I run it?" it becomes code analysis and will be much easier for us to do if you send us the sample project.


Reply | PowerTCP Web for ActiveX Topics | Forums   
This site is powered by PowerTCP WebServer Tool PowerTCP WebServer for ActiveX