Re: How do I tell an object to free up an owned object from thta object itself?
From: Bo Berglund (bo.berglund_at_telia.com)
Date: 12/29/03
- Next message: K Adams: "Reading Published Properties"
- Previous message: Martin Strand: "Re: No help required"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 29 Dec 2003 20:46:43 GMT
Sorry for not responding to your elaborate comment earlier, I switched
to the borland public newsserver and forgot to check this group...
Do you have any suggestions on how I should approach the problem
without actually implementing the events in my own class code?
It seems that you advocate leaving all of this at the server level,
right?
The core problem I have is that I want to have a service that handles
the processing through a processing object and that each client should
get its own object instance. If this object does not implement the
communications events, how then can I communicate with the object?
If I don't implement event code then I assume the events are triggered
on the server level and then how am I going to be able to direct the
interactions correctly between the client and the created object?
A rough skeleton suggestion would help a lot.
Observation:
My scheme of periodically checking on the server level if there are
any unused sockets hanging around and if so freeing them seems to
cause the service to exit with an access violation error after a
while. It seems like in about 24-36 hours this happens when I have set
the socket checking timeout to something like a minute.
So I guess that this way of stopping the "socket leak" is also
flawed...
/Bo
On Sat, 04 Oct 2003 12:36:58 GMT, "David Reeve"
<dree4456@big-pond.net.au> wrote:
>"Bo Berglund" <bo.berglund@telia.com> wrote in message
>news:er2qnvcqasiehaiatrljpfqbgb1ujh0l9t@4ax.com...
>
>OK ... I'm pretty sure I understand the problem. However, explaining it
>without waving my arms about is going to be difficult. I have a map of
>ScktComp.pas which I built up from many hours of stepping the code. I'll
>tidy it up one day so I can put it up for others to see. For the moment,
>apologies to the ng for the long post.
>
>The root of the problem is that you are grabbing the socket passed in the
>OnClientConnect event and messing with it. It is closely coupled to, and
>managed by the TServerWinSocket instance, which is referenced by the socket
>property of your top level TServerSocket. If you intercept its OnSocketEvent
>eventhandler, then you break this connection with the inevitable result that
>client-end connections will be left hanging and so on.
>
>The TServerSocket wraps a TServerWinSocket which implements the basic
>server functionality, ie the ability to manage simultaneous client
>connections. Let's forget TServerSocket for the moment except to note that
>its main purpose is the hide the complexities of swapping between blocking
>and non-blocking modes, and concentrate on TServerWinSocket. From now on
>I'll refer to the TServerWinSocket as the Server. In the non blocking mode,
>the OnClientxxxx events of this Server are mapped to the outer wrapping
>object.
>
>Staying with the non blocking mode, on a call to Open, the ServerSocket
>creates a thread of execution which listens for incoming connections at the
>designated port. When a connection is detected, the Server creates a
>TServerClientWinSocket object within the context of the main thread and
>furnishes this with a physical socket it gets from the OS. This new object I
>will refer to as a ClientConnection. ClientConnections are windowed, and
>communicate with the underlying sockets layer by messaging.
>
>For every new ClientConnection, a reference to it is added to a connection
>list held by the Server and, ** most importantly**, the OnSocketEvent of
>the ClientConnection is linked to a handler in the the Server. When a client
>disconnects, the ClientConnection object is destroyed, its physical socket
>relinquished to the OS, and its reference removed from the connection list.
>Now once the Server has finished with these events arising from the
>underlying sockets, they are passed, with some filtering and crossmapping,
>to the events you know and love at top level TServerSocket.
>
>One of the causes of confusion is the fact that both the Server object and
>the ClientConnection object have TCustomWinSocket as their ancestor, and it
>is this class that contains the bulk of the functionality. When you are
>stepping code, it is a constant hassle to keep track of whether you are in a
>Server object or a ClientConnection object as it is the same physical code.
>
>So what is happening is the following.....
>When the client connects....
> ClientConnection.FOnSocketEvent := Server.HandleClientSocketEvent
>When you handle the OnClientConnectEvent.....
> ClientConnection.FOnSocketEvent := Bo'sObject.HandleClientSocketEvent
>And the Server is basically broken :-)
>
>
>> A) Yes, it is possible to call Self.Free from within the handler
>> object itself in the SocketEvent method if a disconnect is detected.
>>
>> B) But I cannot do the FSocket.Free in this destructor. It causes an
>> access violation. So I left that for the TServerSocket to handle.
>>
>
>Makes sense, your FSocket is a reference to a ClientConnection object, and
>another reference to it will exist in the Server's connection list. When the
>latter closes an attempt will be made to free it.
>
>> C) I tested running a sequence of connect/disconnect from the client
>> (clean, without forcing the application to exit). I had added a
>> function to the server object to count the connections and list the
>> client address for those connections that were active. Results:
>> - The connections list accumulates over time. It does not look like
>> the TServerSocket frees up sockets that are no longer in use.
>> - The connections associated with clients that were forcibly closed
>> (for example in Delphi debugger by stopping the program) are listed
>> with active connections.
>>
>
>Makes sense. You have broken the link between the Server object and every
>new ClientConnection object **after** the reference to the new object has
>been added to the Server's connection list.
>
>> D) So I had to add a server side timer that every 15 seconds runs
>> through the connections list and frees all sockets that are not
>> connected.
>>
>
>Yep.... the connection list is valid, so provided you don't free them in
>your handler, this will work. BUT you shouldn't need to do this :-)
>
>> E) A strange thing is the following:
>> If I stop listening (TServerSocket.Close) then all client sockets are
>> disconnected. I can thus not have the server listen for a given time
>> and allow connections, then stop listening but still let the already
>> connected clients continue communicating. Strange, this makes it more
>> difficult to set an upper limit on the number of clients allowed.
>>
>
>Not strange. Quite understandable as the Server will work through its
>connection list, which will be valid in so far as the ClientConnection
>objects exist, though maybe not connected. The Server object controls the
>lifetime of its ClientConnections. It doesn't make sense to allow
>connections to live on without their controller. Well not as far as this
>architecture is concerned.
>
>> Finally, referring to one of your items:
>> No, I dont't keep a list of created handlers in the server. They are
>> just created in the OnClientConnect and are allowed to live
>> independent lives. But the owner is the server object and they are
>> descendants of TComponent so behind the scenes I guess some sort of
>> list is kept nevertheless....
>>
>No problem here. TServerSocket ultimately descends from TComponent, and thus
>your handler objects will be inserted in its component list on creation, and
>will be freed when the TServerSocket is destroyed.
>
>
>Dave
>
Bo Berglund
bo.berglund@telia.com
- Next message: K Adams: "Reading Published Properties"
- Previous message: Martin Strand: "Re: No help required"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|