Re: Control lifecycle thoughts ...
- From: Mark McLoughlin <mark skynet ie>
- To: Michael Meeks <michael ximian com>
- Cc: Darin Adler <darin eazel com>, <gnome-components-list gnome org>
- Subject: Re: Control lifecycle thoughts ...
- Date: Thu, 25 Oct 2001 10:19:49 +0100 (IST)
Hi Michael,
On Wed, 24 Oct 2001, Michael Meeks wrote:
>
> Hi Darin,
>
> I've been considering the lifecycle issues - and coming up with an
> improved method for Gnome 2.0; and I'd greatly appreciate your comments on
> my thoughts, in libbonoboui/doc/control.txt
This all looks fine to me except ...
> * Creation interaction (A)
>
> 1. Control creation
> 2. Passes it's reference
> 3. _control_frame_new
> 4. creates ControlFrame
> 5. creates Socket
> 6. _control_frame_bind_to_control
> 7. takes a B. Control ref.
> 8. Control->setFrame
> 9. takes a C. control_frame ref
^^^
This should be a B. ref yes ?
> * CORBA connection 'broken' signal
>
> This signal is totaly unaffected by CORBA reference counting,
> and will happily leave an object with a broken connection - but we'll
> get a nice signal.
>
> We only get this signal using Unix Domain Sockets - FIXME,
> check whether this is at all portable - are we notified by poll of
> broken connections on Solaris etc. or do we need periodic ping
> evilness there; if so - can we use some other mechanism.
In ORBit2 I made the assumption that if there has been a
passive close on your socket, you get a POLLIN from poll and EOF when
you read the socket.
I've just hacked up some code to test this assumption - it
works, for UDS and IP on both Solaris and Linux. The code is attached.
Note that POLLHUP isn't useful to us because, on a passive
close, we only get for UDS and only on Linux.
Good Luck,
Mark.
/*
* Socket hangup test.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Author: Mark McLoughlin <mark skynet ie>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/un.h>
#include <netinet/in.h>
#define PORTNUM 3030
#define UDS_PATH "/tmp/uds-0001"
typedef enum {
TEST_IP4,
TEST_UDS
} TestCase;
void try_read (int fd)
{
char buf [10];
int n;
fprintf (stderr, "Trying a read.\n");
n = read (fd, buf, 10);
if (!n)
fprintf (stderr, "EOF. Connection dead.\n");
else
fprintf (stderr, "Doh. Connection okay.\n");
}
void server (TestCase test_case)
{
struct sockaddr_in servaddr_in;
struct sockaddr_un servaddr_un;
struct sockaddr *servaddr;
struct pollfd fds[1];
int listenfd;
int n;
int servaddr_len;
switch (test_case) {
case TEST_IP4:
memset (&servaddr_in, 0, sizeof (struct sockaddr_in));
servaddr_in.sin_family = AF_INET;
servaddr_in.sin_port = htons (PORTNUM);
servaddr_in.sin_addr.s_addr = htonl (INADDR_ANY);
servaddr = (struct sockaddr *)&servaddr_in;
servaddr_len = sizeof (struct sockaddr_in);
break;
case TEST_UDS:
memset (&servaddr_un, 0, sizeof (struct sockaddr_un));
servaddr_un.sun_family = AF_UNIX;
strcpy (servaddr_un.sun_path, UDS_PATH);
servaddr = (struct sockaddr *)&servaddr_un;
servaddr_len = sizeof (struct sockaddr_un) -
sizeof (servaddr_un.sun_path) +
strlen (UDS_PATH);
break;
default:
break;
}
listenfd = socket (servaddr->sa_family, SOCK_STREAM, 0);
if (listenfd == -1)
return;
bind (listenfd, servaddr, servaddr_len);
n = listen (listenfd, 5);
if (n == -1)
return;
fds [0].fd = accept (listenfd, (struct sockaddr *)NULL, NULL);
if (fds [0].fd == -1)
return;
fds [0].events = POLLIN|POLLPRI;
n = poll (fds, 1, -1);
if (n != 1)
return;
if (fds [0].revents | POLLIN) {
fprintf (stderr, "poll returned POLLIN.\n");
try_read (fds [0].fd);
}
else
fprintf (stderr, "poll failed to return POLLIN.\n");
}
void client (TestCase test_case)
{
struct sockaddr_in servaddr_in;
struct sockaddr_un servaddr_un;
struct sockaddr *servaddr;
int fd;
int n;
int servaddr_len;
switch (test_case) {
case TEST_IP4:
memset (&servaddr_in, 0, sizeof (struct sockaddr_in));
servaddr_in.sin_family = AF_INET;
servaddr_in.sin_port = htons (PORTNUM);
servaddr_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
servaddr = (struct sockaddr *)&servaddr_in;
servaddr_len = sizeof (struct sockaddr_in);
break;
case TEST_UDS:
memset (&servaddr_un, 0, sizeof (struct sockaddr_un));
servaddr_un.sun_family = AF_UNIX;
strcpy (servaddr_un.sun_path, UDS_PATH);
servaddr = (struct sockaddr *)&servaddr_un;
servaddr_len = sizeof (struct sockaddr_un) -
sizeof (servaddr_un.sun_path) +
strlen (UDS_PATH);
break;
default:
break;
}
fd = socket (servaddr->sa_family, SOCK_STREAM, 0);
if (fd == -1)
return;
n = connect (fd, servaddr, servaddr_len);
if (n == -1)
return;
*((char *)NULL) = 0; /* dump core */
}
int main (int argc, char **argv)
{
pid_t pid;
fprintf (stderr, "IP4 test.\n");
if (pid = fork ())
server (TEST_IP4);
else {
sleep (1);
client (TEST_IP4);
return 0;
}
waitpid (pid, NULL, 0);
fprintf (stderr, "UDS test.\n");
unlink (UDS_PATH);
if (pid = fork ())
server (TEST_UDS);
else {
sleep (1);
client (TEST_UDS);
return 0;
}
waitpid (pid, NULL, 0);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]