1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 20:38:08 +01:00

- new function in WINGs: WMSetConnectionShutdownOnClose()

- new callback in the ConnectionDelegate structure: canResumeSending
- replaced setpgid() with setsid() when starting kids, to allow them to
  survive if wmaker (the parent) dies.
- a few cleanups.
This commit is contained in:
dan
2002-09-09 04:25:51 +00:00
parent 048b43aea4
commit d4de3d0a45
11 changed files with 115 additions and 25 deletions

View File

@@ -1,3 +1,10 @@
Changes since wmaker 0.80.1:
............................
- added WMSetConnectionShutdownOnClose()
- added an extra member to the ConnectionDelegate: canResumeSending
see NEWS for details.
Changes since wmaker 0.80.0: Changes since wmaker 0.80.0:
............................ ............................

View File

@@ -28,6 +28,7 @@ static void didInitialize(ConnectionDelegate *self, WMConnection *cPtr);
static ConnectionDelegate socketDelegate = { static ConnectionDelegate socketDelegate = {
NULL, /* data */ NULL, /* data */
NULL, /* canResumeSending */
NULL, /* didCatchException */ NULL, /* didCatchException */
connectionDidDie, /* didDie */ connectionDidDie, /* didDie */
didInitialize, /* didInitialize */ didInitialize, /* didInitialize */

View File

@@ -42,6 +42,7 @@ static WMConnection *serverPtr = NULL;
static ConnectionDelegate socketDelegate = { static ConnectionDelegate socketDelegate = {
NULL, /* client data */ NULL, /* client data */
NULL, /* canResumeSending */
NULL, /* didCatchException */ NULL, /* didCatchException */
connectionDidDie, /* didDie */ connectionDidDie, /* didDie */
NULL, /* didInitialize */ NULL, /* didInitialize */

View File

@@ -1,3 +1,55 @@
*** Mon Sep 09 06:58:30 EEST 2002 - Dan
New delegate for the WMConnection class
---------------------------------------
ConnectionDelegate structure has a new member: canResumeSending.
The purpose of this callback is to notify you that you can resume sending
data over a WMConnection.
It works in the following manner:
WMSendConnectionData() can return 3 values: -1, 0, 1
-1 - means that the connection has died. you should stop sending data and
close the connection ASAP.
1 - means that the data was succesfully sent
0 - means that the data (or part of it) was not sent. however, it was saved
in a queue and the library will try to send it later when possible.
if the return value is 1, you can continue to send the next message, and so
on, until the return value of such a send call will be 0.
In this case you can continue sending, however, the data will not be sent
over the connection because the operating system cannot accept any more data
for the moment. Instead it will be queued inside the library, making your
program's memory footprint increase. If the ammount of data you need to
send is limited and not too big, this shouldn't be a problem, because your
data will be queued and sent when the operating system will notify the
library that sending is possible again.
If this is the case you can just ignore the output of WMSendConnectionData()
and not set a callback for canResumeSending.
However, if the ammount of data you have to send is undetermined and you
also want to keep a small memory footprint for your program (so that it
won't grow until it uses all your available memory ;) ), you will have to
stop sending data over the connection as soon as WMSendConnectionData()
returns with 0. Then you should somehow mark this situation in your program
to avoid it trying to send anymore data until notified that it can resume.
(You should have also set a canResumeSending callback when you initialized
your WMConnection object because else you cannot be notified when to resume.)
Now, when you receive such a 0 from the send operation, your last sent data
is put in a queue inside the library. At a later time when the operating
system notifies the library that sending is possible again, the library will
resume to send the data that is saved in the queue. After it will be able to
send all the data in the queue, the canResumeSending callback will be
called, letting you know that not only you can resume sending because the
operating system is again able to send data, but also that the queue was
completely flushed.
From the canResumeSending callback, you should again update the status of
your program marking that it can send again, and then resume sending the
data from where you were left.
*** Thu Oct 04 06:00:09 EEST 2001 -Dan *** Thu Oct 04 06:00:09 EEST 2001 -Dan

View File

@@ -184,8 +184,9 @@ typedef struct {
typedef struct ConnectionDelegate { typedef struct ConnectionDelegate {
void *data; void *data;
void (*didCatchException)(struct ConnectionDelegate *self, void (*canResumeSending)(struct ConnectionDelegate *self, WMConnection *cPtr);
WMConnection *cPtr);
void (*didCatchException)(struct ConnectionDelegate *self, WMConnection *cPtr);
void (*didDie)(struct ConnectionDelegate *self, WMConnection *cPtr); void (*didDie)(struct ConnectionDelegate *self, WMConnection *cPtr);
@@ -977,6 +978,8 @@ Bool WMSetConnectionNonBlocking(WMConnection *cPtr, Bool flag);
Bool WMSetConnectionCloseOnExec(WMConnection *cPtr, Bool flag); Bool WMSetConnectionCloseOnExec(WMConnection *cPtr, Bool flag);
void WMSetConnectionShutdownOnClose(WMConnection *cPtr, Bool flag);
void* WMGetConnectionClientData(WMConnection *cPtr); void* WMGetConnectionClientData(WMConnection *cPtr);
void WMSetConnectionClientData(WMConnection *cPtr, void *data); void WMSetConnectionClientData(WMConnection *cPtr, void *data);

View File

@@ -121,6 +121,7 @@ typedef struct W_Connection {
char *protocol; char *protocol;
Bool closeOnRelease; Bool closeOnRelease;
Bool shutdownOnClose;
Bool wasNonBlocking; Bool wasNonBlocking;
Bool isNonBlocking; Bool isNonBlocking;
@@ -192,9 +193,10 @@ inputHandler(int fd, int mask, void *clientData)
return; return;
if ((mask & WIWriteMask)) { if ((mask & WIWriteMask)) {
int result;
if (cPtr->state == WCInProgress) { if (cPtr->state == WCInProgress) {
Bool failed; Bool failed;
int result;
int len = sizeof(result); int len = sizeof(result);
WCErrorCode = 0; WCErrorCode = 0;
@@ -228,7 +230,10 @@ inputHandler(int fd, int mask, void *clientData)
if (failed) if (failed)
return; return;
} else if (cPtr->state == WCConnected) { } else if (cPtr->state == WCConnected) {
WMFlushConnection(cPtr); result = WMFlushConnection(cPtr);
if (result>0 && cPtr->delegate && cPtr->delegate->canResumeSending) {
(*cPtr->delegate->canResumeSending)(cPtr->delegate, cPtr);
}
} }
} }
@@ -376,6 +381,7 @@ createConnectionWithSocket(int sock, Bool closeOnRelease)
cPtr->sendTimeout.timeout = DefaultTimeout; cPtr->sendTimeout.timeout = DefaultTimeout;
cPtr->sendTimeout.handler = NULL; cPtr->sendTimeout.handler = NULL;
cPtr->closeOnRelease = closeOnRelease; cPtr->closeOnRelease = closeOnRelease;
cPtr->shutdownOnClose = 1;
cPtr->outputQueue = cPtr->outputQueue =
WMCreateArrayWithDestructor(16, (WMFreeDataProc*)WMReleaseData); WMCreateArrayWithDestructor(16, (WMFreeDataProc*)WMReleaseData);
cPtr->state = WCNotConnected; cPtr->state = WCNotConnected;
@@ -627,7 +633,9 @@ void
WMDestroyConnection(WMConnection *cPtr) WMDestroyConnection(WMConnection *cPtr)
{ {
if (cPtr->closeOnRelease && cPtr->sock>=0) { if (cPtr->closeOnRelease && cPtr->sock>=0) {
if (cPtr->shutdownOnClose) {
shutdown(cPtr->sock, SHUT_RDWR); shutdown(cPtr->sock, SHUT_RDWR);
}
close(cPtr->sock); close(cPtr->sock);
} }
@@ -648,7 +656,9 @@ void
WMCloseConnection(WMConnection *cPtr) WMCloseConnection(WMConnection *cPtr)
{ {
if (cPtr->sock>=0) { if (cPtr->sock>=0) {
if (cPtr->shutdownOnClose) {
shutdown(cPtr->sock, SHUT_RDWR); shutdown(cPtr->sock, SHUT_RDWR);
}
close(cPtr->sock); close(cPtr->sock);
cPtr->sock = -1; cPtr->sock = -1;
} }
@@ -743,10 +753,18 @@ WMEnqueueConnectionData(WMConnection *cPtr, WMData *data)
} }
/*
* Return value:
* -1 - not connected or connection died while sending
* 0 - couldn't send the data (or part of it). data is saved in a queue
* and will be sent when possible. after it is sent the canResumeSending
* callback will be called.
* 1 - data was succesfully sent
*/
int int
WMSendConnectionData(WMConnection *cPtr, WMData *data) WMSendConnectionData(WMConnection *cPtr, WMData *data)
{ {
int bytes, pos, len, totalTransfer; int bytes, pos, len;
TimeoutData *tPtr = &cPtr->sendTimeout; TimeoutData *tPtr = &cPtr->sendTimeout;
const unsigned char *dataBytes; const unsigned char *dataBytes;
@@ -767,8 +785,6 @@ WMSendConnectionData(WMConnection *cPtr, WMData *data)
return 0; return 0;
} }
totalTransfer = 0;
while (WMGetArrayItemCount(cPtr->outputQueue) > 0) { while (WMGetArrayItemCount(cPtr->outputQueue) > 0) {
data = WMGetFromArray(cPtr->outputQueue, 0); data = WMGetFromArray(cPtr->outputQueue, 0);
dataBytes = (const unsigned char *)WMDataBytes(data); dataBytes = (const unsigned char *)WMDataBytes(data);
@@ -793,7 +809,7 @@ WMSendConnectionData(WMConnection *cPtr, WMData *data)
WMAddInputHandler(cPtr->sock, WIWriteMask, WMAddInputHandler(cPtr->sock, WIWriteMask,
inputHandler, cPtr); inputHandler, cPtr);
} }
return totalTransfer; return 0;
default: default:
WCErrorCode = errno; WCErrorCode = errno;
cPtr->state = WCDied; cPtr->state = WCDied;
@@ -804,7 +820,6 @@ WMSendConnectionData(WMConnection *cPtr, WMData *data)
} }
} }
pos += bytes; pos += bytes;
totalTransfer += bytes;
} }
WMDeleteFromArray(cPtr->outputQueue, 0); WMDeleteFromArray(cPtr->outputQueue, 0);
cPtr->bufPos = 0; cPtr->bufPos = 0;
@@ -812,13 +827,18 @@ WMSendConnectionData(WMConnection *cPtr, WMData *data)
WMDeleteTimerHandler(tPtr->handler); WMDeleteTimerHandler(tPtr->handler);
tPtr->handler = NULL; tPtr->handler = NULL;
} }
/*if (cPtr->handler.write) {
WMDeleteInputHandler(cPtr->handler.write);
cPtr->handler.write = NULL;
}*/
}
if (cPtr->handler.write) { if (cPtr->handler.write) {
WMDeleteInputHandler(cPtr->handler.write); WMDeleteInputHandler(cPtr->handler.write);
cPtr->handler.write = NULL; cPtr->handler.write = NULL;
} }
}
return totalTransfer; return 1;
} }
@@ -952,6 +972,13 @@ WMSetConnectionCloseOnExec(WMConnection *cPtr, Bool flag)
} }
void
WMSetConnectionShutdownOnClose(WMConnection *cPtr, Bool flag)
{
cPtr->shutdownOnClose = ((flag==0) ? 0 : 1);
}
void* void*
WMGetConnectionClientData(WMConnection *cPtr) WMGetConnectionClientData(WMConnection *cPtr)
{ {

View File

@@ -603,7 +603,6 @@ W_HandleInputEvents(Bool waitForInput, int inputfd)
W_FlushASAPNotificationQueue(); W_FlushASAPNotificationQueue();
/* --oldway-- return ((inputfd < 0) ? (count > 0) : FD_ISSET(inputfd, &rset));*/
return (count > 0); return (count > 0);
#else /* not HAVE_SELECT, not HAVE_POLL */ #else /* not HAVE_SELECT, not HAVE_POLL */
Neither select nor poll. You lose. Neither select nor poll. You lose.

View File

@@ -14,7 +14,7 @@ WHandleEvents()
W_CheckTimerHandlers(); W_CheckTimerHandlers();
/* Do idle and timer stuff while there are no input events */ /* Do idle and timer stuff while there are no input events */
/* Do not wait for input here. just peek to se if input is available */ /* Do not wait for input here. just peek to see if input is available */
while (!W_HandleInputEvents(False, -1) && W_CheckIdleHandlers()) { while (!W_HandleInputEvents(False, -1) && W_CheckIdleHandlers()) {
/* dispatch timer events */ /* dispatch timer events */
W_CheckTimerHandlers(); W_CheckTimerHandlers();

View File

@@ -15,7 +15,7 @@ AC_INIT(src/WindowMaker.h)
AM_INIT_AUTOMAKE(WindowMaker, 0.80.1) AM_INIT_AUTOMAKE(WindowMaker, 0.80.2)
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
@@ -100,7 +100,7 @@ dnl not used anywhere
dnl AC_FUNC_MEMCMP dnl AC_FUNC_MEMCMP
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp setpgid atexit mallinfo mkstemp snprintf vsnprintf asprintf vasprintf) AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp setsid atexit mallinfo mkstemp snprintf vsnprintf asprintf vasprintf)
dnl ripped from samba dnl ripped from samba

View File

@@ -2979,8 +2979,8 @@ execCommand(WAppIcon *btn, char *command, WSavedState *state)
SetupEnvironment(scr); SetupEnvironment(scr);
#ifdef HAVE_SETPGID #ifdef HAVE_SETSID
setpgid(0, 0); setsid();
#endif #endif
args = malloc(sizeof(char*)*(argc+1)); args = malloc(sizeof(char*)*(argc+1));

View File

@@ -307,8 +307,8 @@ ExecuteShellCommand(WScreen *scr, char *command)
SetupEnvironment(scr); SetupEnvironment(scr);
#ifdef HAVE_SETPGID #ifdef HAVE_SETSID
setpgid(0, 0); setsid();
#endif #endif
execl(shell, shell, "-c", command, NULL); execl(shell, shell, "-c", command, NULL);
wsyserror("could not execute %s -c %s", shell, command); wsyserror("could not execute %s -c %s", shell, command);