Dear Matthias and Paul,
Aaron Sloman forwarded your question concerning sockets to the
popforum mailing list. As I am having a few difficulties with
sockets in Poplog I found your post very interesting.
My first suggestion is that you followup your question with a mailing
to popforum@cs.bham.ac.uk giving a brief description of which
operating system you are running on. If it is a Linux platform you
need to specify which kernel version it is, too. Different operating
system have surprisingly different limits with regard to sockets,
although Linux is excellent by and large.
My second thought is that you need to check whether or not you have
got some kind of leak. The way I would handle this is that I would
wrap each and every socket allocation call with, say, "track_socket".
Writing off the top of my head it would look something like this.
(You will have to tweak this as I haven't had time to transfer it to
a working Poplog system & check it out.)
;;; A temporary hash table that holds the tracking names you
;;; assign to the sockets.
;;;
define socket_tracking_names =
newanyproperty( [], 8, 1, false, false, false, "tmparg", false, false )
enddefine;
;;; A temporary hash table to keep track of the sockets still in
;;; the heap. Being "tmparg" this implements a weak reference and
;;; does not inhibit garbage collection.
;;;
define socket_tracking_table =
copy( socket_tracking_names )
enddefine;
;;; It would be nice to know about sockets that have actually
;;; been garbage collected. That means using an "=" based bag
;;; (implemented as an "=" based property with a 0 default.)
;;;
define socket_destroyed_table =
newanyproperty(
[], 8, 1, false,
syshash, nonop =, "perm",
0, false
)
enddefine;
;;; We'd like a similar bag to track every socket ever allocated.
define socket_made_table =
copy( socket_destroyed_table )
enddefine;
;;; Stuffs the socket in the tracking table for later review & assign
;;; the tracking name. The socket is returned.
;;;
define track_socket( sock, tname ) -> sock;
tname -> socket_tracking_name( sock );
;;; Set up the destroy action.
procedure( sock );
socket_destroyed_table( tname ) + 1 -> socket_destroyed_table( tname )
endprocedure -> sys_destroy_action( sock );
;;; Enter the socket in the tracking table.
true -> socket_tracking_table( sock );
;;; And record it as having been allocated.
socket_made_table( tname ) + 1 -> socket_made_table( tname );
enddefine;
Then at an appropriate point (e.g. when the MISHAP intrudes) you can
review the two tables.
define review();
nprintf( 'EXTANT SOCKETS', [] );
fast_appproperty(
socket_tracking_table,
procedure( sock, _ );
nprintf(
' %p (%p)',
[%
sock.socket_tracking_name,
sock.isclosed and "closed" or "open"
%]
)
endprocedure
);
nprintf( 'EXPIRED SOCKETS', [] );
fast_appproperty(
socket_destroyed_table,
procedure( name, count );
nprintf( ' %p * %p', [% name, count %] )
endprocedure
);
nprintf( 'MADE SOCKETS', [] );
fast_appproperty(
socket_made_table,
procedure( name, count );
nprintf( ' %p * %p', [% name, count %] )
endprocedure
);
nprintf( '---', [] );
enddefine;
This will give you some idea of what state the system is actually in.
You could also take the difference of the entries in the
made&destroyed tables. In any case, I think the results are likely
to point the finger either at some unidentified leak in your own
program OR at a low-level Poplog problem.
Hope this helps.
--
Steve
|