[prev in list] [next in list] [prev in thread] [next in thread]
List: apache-modules
Subject: [apache-modules] strange poll/select problem in my apache module
From: Christian Parpart <cparpart () surakware ! net>
Date: 2004-09-09 14:21:07
Message-ID: 200409091621.09807.cparpart () surakware ! net
[Download RAW message or body]
Hi all,
I know, this worked once, but since a few days, it doesn't, and I do *not*
know what I've changed to get this happen.
Well, I have to care about early web client aborts, as well as backend server
aborts while streaming data to the web client (I obviousely got from the
backend server my module is connected to, too).
Well, the best way to achieve this, is, to poll on both.
At very first, I've to register a pre connection hook to catch the web clients
file descriptor.
static void registerHooks(apr_pool_t *p) {
ap_hook_pre_connection(getClientSocket, 0, 0, APR_HOOK_FIRST);
// ...
}
int getClientSocket(conn_rec *conn, void *data) {
apr_os_sock_get(&FClientSocket, reinterpret_cast<apr_socket_t *>(data));
int optval = 1;
setsockopt(FClientSocket, SOL_SOCKET, TCP_NODELAY, &optval,
sizeof(optval));
return OK;
}
Next, on a incoming connection, that belongs to us, I've to handle my stuff as
usual *but* have to watch on early connection aborts on web client side, as
well as on backend server side.
void TChatStreamer::streamPageBody() {
pollfd pfds[2];
pfds[0].fd = FWebClientSocket;
pfds[0].events = POLLIN;
pfds[1].fd = FBackendServerSocket;
pfds[1].events = POLLIN;
while (!FAborted) {
int rv = poll(pfds, 2, 60 * 1000);
if (rv > 0) {
if (pfds[0].revents & POLLIN)
FAborted = true; /* early client abort */
if (pfds[1].revents & POLLIN)
handleEventFromServer(); /* got event from backend server */
} else if (rv == -1) {
FAborted = true;
} else {
handleTimeout();
}
}
logoutClientFromBackendServer(); /* when we finished job, logout webclient */
}
void TChatStreamer::handleEventFromServer() {
std::string input(readLineFd(FBackendServerSocket));
if (input.empty())
handleServerAbort();
else
handleEventFromServer(input);
}
void TChatStreamer::handleTimeout() {
/* send some random HTML comment to web client in order to
keep connection alive */
}
Well done. This is just a rarely abstract code snippet, however, I intent to
send all incoming events I get from the backend server to the web client, so,
the apache module may be understood, to act as a proxy between. Important now
is, that the web client, that also logged in to the backend server via the
apache module, needs also to logout via this.
Of course, lots of user miss the logout button, and just close the webbrowser
in order to sign, that they've done chatting, that is, they do *not* get any
other events (e.g. chat messages) from the backend server via the apache
module. So, the apache module needs to log them out automatically, at least,
let them leave the channel they've currently joined. I repeat, this worked
some day before, but obviousely, actually not. And I do not know why :(
Also, a problem would be, that the module would end into an infinite loop,
when we cannot detect the early (web) client abort.
The problem now. The code above does *not* detect a client abort, poll() -
previousely select() - does not return when the client aborts the connection.
And even more *worse*, when the backend server disconnects its (apache)
clients (e.g. via shutdown), the apache module's request handler just notices
this, *BUT* also notices a client abort, that - of course - was not true.
This is strange, but why? What could have been the problem here?
So, when the backend server (int FBackendServerFd) closes connection, I get
notified via poll() to have *two* closed connections, the backend server
*AND* the webclient.
When I close the connection of the webbrowser (by just closing it), I get even
nothing => the webserver's request handler runs into infinite loop => the
backend server can't get notified about the real dead (web) client => we've
lots of dead ppl in the chat I've to kick each day ;-)
I'd be really really happy, if anyone could give me any hint he has to fix
this issue.
Regards,
Christian Parpart.
--
15:56:10 up 16 days, 3:35, 0 users, load average: 0.52, 0.43, 0.38
[Attachment #3 (application/pgp-signature)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic