Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
using ICS Overbyte component on IntraWeb Problem
#11
I tested the sample application and the behavior is determined by Indy threads.

The user is creating a new window when the application receives an incoming request. Indy will spawn a new thread for it.

This new window is owned by the Indy worker thread. As soon as the request is processed in the async event, the thread is freed so are the owned windows.

That's why the window handle becomes invalid.

BTW: the same problem doesn't happen in Http.sys IW application because there are a fixed number of worker threads that are not destroyed.
Reply
#12
This was my response in Delphi-praxis forum:

I've just tested his test application (without ICS, but the same issue will definitely happen). There is nothing wrong with IntraWeb.


He's using an Indy-based IntraWeb server. He creates a window handle when his application is receiving an incoming request. The Indy HTTP server spawns a worker thread which is freed afterward. The window handle is released when the thread is destroyed. Then he tries to use the same window handle in a subsequent request, from another thread (there is no guarantee that the original thread which created the window handle hasn't been destroyed).


This is documented here: https://docs.microsoft.com/en-us/windows...g-a-thread


BTW: his example works when using Http.sys-based IntraWeb application (not Indy) because the threads are obtained from a thread pool and recycled, so the windows created in one request will be still valid in a subsequent request (although I don't recommend his way of using it at all).

Quote:From FPiette:
In the IntraWeb forum, they just want to hide a problem they overlooked with IntraWeb and they want you to use their product.


Given that the application behavior is not only expected but also correct, your statement above is obviously false.
Reply
#13
Quote:ICS uses messages which do NOT work in threads.


That is completely false. Read Microsoft documentation.


Quote:Francois even tells you this in his first message.

That is not what I said. I said that ICS make use of messages and the thread using ICS must have a message pump.



Quote:Using ICS in a threaded application is a fools errand.


That is completely stupid. Im being as kind as I can.


Quote:ICS is a fine product, but was never designed for threads.


ICS has been designed to be also used with thread. Since ICS is non blocking, a single thread is able to handle hundreds of communications simultaneously. You only need to use multi threading if your application code is blocking (For example, some database components are not asynchronous so you must use a thread while lengthy SQL request is running).

Another use case is when you have to handle THOUSANDS of simultaneous, active communications, then use a thread for each 500 connections.

Using thread for each connection is NOT recommended at all, it is a large waste of resources and that is what Indy is doing. Bad.

Of course ICS may also be used with a thread for each connection if you like to waste resources. Those thread need a message pump as explained in Microsoft documentation.


Quote:AllocateHWnd is not thread-safe. This has been known for a long time now.


ICS has his own AllocateHWnd method that is thread safe. It make use of a critical section to protect the class registration (GetClassInfo and RegisterClass) and then use CreateWindowEx to create the handle. For those interested, look at TIcsWndHandler.AllocateHWnd in unit OverbyteIcsWndControl.

Additionally, TWSocket has two methods ThreadDetach and ThreadAttach to move the messages from one thread to another. For example you may have a thread to run the listening server socket and one other thread to handle client socket (That is what Indy is doing). The server thread create the client socket and - if you like - you can detach it from that thread and attach it to another one.


Quote:He's using an Indy-based IntraWeb server. He creates a window handle when his application is receiving an incoming request. The Indy HTTP server spawns a worker thread which is freed afterward. The window handle is released when the thread is destroyed. Then he tries to use the same window handle in a subsequent request, from another thread (there is no guarantee that the original thread which created the window handle hasn't been destroyed).


This is exactly the kind of use case where ICS TWSocket.ThreadDetach and ThreadAttach are made for. Of course this doesn't remove the need for a message pump. TWSocket also has a method which is a message pump so that when a thread has no message pump, this method can be used until the communication is closed.

Finally, as I said in my first reply to the original discussion, it is simpler to put all ICS stuff in a single thread created from the IntraWeb thread handling the client.
Reply
#14
Francois - Im going to keep this short.

1) Messages date back to Windows before it could thread and were designed to allow cooperative multitasking in a single system thread.
2) ICS is built to its core around non blocking sockets using windows messages.

I did not say ICS could not work in a thread, but its clearly designed to work around messages which are designed for many sockets on one thread. Indy is specifically designed for threads. You have taken up a totally untenable position and for no apparent reason other than ego. The user is already using Indy internally. There is *no benefit* to using ICS in this specific situation and many drawbacks for no gain at all. You've literally chosen the one area where Indy clearly beats ICS without a doubt. They are both free products.

"Using thread for each connection is NOT recommended at all, it is a large waste of resources and that is what Indy is doing. Bad"

I'm not even going to go there. We've been down this route for decades. You are more than biased here and being disingenuous as well. Your statement is incorrect, but I simply dont have time to waste regurgitating it all yet again. If threads are that bad, then you might want to tell Microsoft and everyone else.

This is literally like trying to type Chinese on a English keyboard. Yeah, it can be dont but its not what the keyboard was designed for. Indy would work without *any prerequisites or patched methods*.... here are the steps to make Indy work in a thread:

1) Nothing.

With Indy there would be no forum post here at all asking "how do I make it work in threads".

Really you dont have anything better to do than fight over which free product a user should use especially when one is clearly better suited in a very specific situation and the user already is using Indy implicitly because IntraWeb is using it?

And you totally ignore things like deploying in IIS which doesnt offer the IntraWeb application a main application thread and in which there is no main thread message queue and permissions can even impact your ability to create one in some cases. And thread pooling, and thread ownership of the windows handles... the list goes on.....

When a user wants to handle multiple sockets on a single thread I recommend ICS, despite the fact that Indy CAN do that too. Why? Because Indy is designed for threads, an in that situation ICS is superior as it was designed for it. Neither ICS nor Indy are the magic solution for every situation.

Just let this thread pass. I'm sure you have something better to do with your time.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)