Revision 1.5 |
Revision 1.10 |
Line 6 |
Line 6 |
#include <sys/types.h> #include <fcntl.h> #include "defines.h" 
|
#include <sys/types.h> #include <fcntl.h> #include "defines.h" 
|
#include "pth.h"
|
#include "cow.h"
|
|
#include "schedule.h"
|
#include "config.h"
|
#include "config.h"
|
#include "pmsg.h"
|
|
|
|
// response.h/c
|
void *depot(void *_arg) {
|
int response_503(int);
// defined in cow.c
extern int cow_cur_conn;
extern pth_barrier_t init_bar;
void *depot(void *_arg)
{
|
|
int max = (int)_arg; int top = 0; pth_msgport_t mp;
|
int max = (int)_arg; int top = 0; pth_msgport_t mp;
|
Line 44 |
Line 36 |
} msg = (pmsg *) pth_msgport_get(mp); if (NULL == msg) {
|
} msg = (pmsg *) pth_msgport_get(mp); if (NULL == msg) {
|
perror("pth_msgport_get (47)");
raise(SIGSEGV);
|
perror("pth_msgport_get");
exit(-1);
|
} Stack[top++] = msg; }
|
} Stack[top++] = msg; }
|
Line 53 |
Line 45 |
pth_barrier_reach(&init_bar); /* end of initialization */ // suspend hands on the stack
|
pth_barrier_reach(&init_bar); /* end of initialization */ // suspend hands on the stack
|
#include "schedule.h" /* enabler|disable SUSPention of handler */
|
|
#ifdef SUSP for (i = 0; i < top; i++) { if (FALSE == pth_suspend(Stack[i]->id)) { perror("pth_suspend fail"); exit(-1); }
|
#ifdef SUSP for (i = 0; i < top; i++) { if (FALSE == pth_suspend(Stack[i]->id)) { perror("pth_suspend fail"); exit(-1); }
|
|
--cow_nohands_running;
|
} #endif /* SUSP */
|
} #endif /* SUSP */
|
Line 83 |
Line 75 |
/* Get all pending messages from the message port */ pending = pth_msgport_pending(mp); for (i = 0; i < pending; ++i) {
|
/* Get all pending messages from the message port */ pending = pth_msgport_pending(mp); for (i = 0; i < pending; ++i) {
|
msg = (pmsg *) pth_msgport_get(mp);
if (msg == NULL) {
|
msg = (pmsg*) pth_msgport_get(mp);
assert(msg != NULL);
|
perror(__FILE__ " :: pth_msgport_get");
raise(SIGSEGV);
}
|
|
/* * Is this a PUSH message (i.e. handler finished processing * a request and wants to return to the pool)? */ if (PUSH == msg->act) {
|
/* * Is this a PUSH message (i.e. handler finished processing * a request and wants to return to the pool)? */ if (PUSH == msg->act) {
|
cow_cur_conn--;
|
|
assert(top < max); Stack[top++] = msg; #ifdef SUSP
|
assert(top < max); Stack[top++] = msg; #ifdef SUSP
|
Line 103 |
Line 91 |
perror("pth_suspend failed in depot.c"); exit(-23); }
|
perror("pth_suspend failed in depot.c"); exit(-23); }
|
|
--cow_nohands_running;
|
#endif /* SUSP */
|
#endif /* SUSP */
|
/*
* Otherwise, the message should be a POP (i.e. we just
* got a new request and need to assign it to one of the
* handlers from the pool.
*/
|
/*
* Otherwise, the message should be a POP (i.e. we just
* got a new request and need to assign it to one of the
* handlers from the pool.
*/
|
} else if (POP == msg->act) { /*
|
} else if (POP == msg->act) { /*
|
* Set the message's action field to 'NONE' -- this tells
* the main accept thread that it can recycle the message
* structure.
|
* Set the message's action field to 'NONE' -- not really
* necessary anymore, but it should help us catch bugs if we
* start reusing messages we shouldn't be.
|
*/ msg->act = NONE; /*
|
*/ msg->act = NONE; /*
|
* Prevent handler pool underflow; just send back a 503 error.
* An alternative would be to spawn a new handler thread here
* (see farther down).
|
* Prevent handler pool underflow; just send back a 503 error
* if there are no available handlers. An alternative would
* be to spawn a new handler thread here (see farther down).
|
*/ if (top <= 0) {
|
*/ if (top <= 0) {
|
pth_yield(NULL);
response_503(msg->fd);
if (close(msg->fd)) {
if (EBADF != errno) {
perror(__FILE__ " :: close");
exit(errno);
}
}
|
reqnode* rn = (reqnode*)msg;
/* Send back 'unavailable' message and close connection */
#ifdef USE_TCPCORK
STATIC_RESPONSE(msg->fd, 503);
cow_close_socket(msg->fd);
#else
STATIC_RESPONSE(msg->buf, 503);
|
|
cow_close_socket(msg->buf);
#endif
--cow_cur_conn;
/* Return the message structure to the pmsg pool */
rn->next = pmsgpool_first;
pmsgpool_first = rn;
|
continue; } /**********************************************************************
|
continue; } /**********************************************************************
|
Line 146 |
Line 142 |
pth_spawn (attr, handler, (void *) ((long) msg->fd)); **********************************************************************/
|
pth_spawn (attr, handler, (void *) ((long) msg->fd)); **********************************************************************/
|
/* Create a message structure to send to the assigned handler */
if (NULL == (new_msg = (pmsg *) malloc(sizeof(pmsg)))) {
printf("Failed to malloc pmsg for new request as %s:%d\n",
__FILE__, __LINE__);
exit(-1);
}
new_msg->fd = msg->fd;
|
|
#ifdef SUSP /* Put the assigned handler back on the scheduling queue */ if (FALSE == pth_resume(Stack[top - 1]->id)) { perror("pth_resume in depot failed"); exit(-22); }
|
#ifdef SUSP /* Put the assigned handler back on the scheduling queue */ if (FALSE == pth_resume(Stack[top - 1]->id)) { perror("pth_resume in depot failed"); exit(-22); }
|
|
++cow_nohands_running;
|
#endif /* Decrement the number of handlers remaining in the pool */
|
#endif /* Decrement the number of handlers remaining in the pool */
|
Line 167 |
Line 156 |
/* Forward the request to the handler */ if (TRUE != pth_msgport_put(Stack[top]->mp,
|
/* Forward the request to the handler */ if (TRUE != pth_msgport_put(Stack[top]->mp,
|
(pth_message_t *)new_msg)) {
|
(pth_message_t *)msg)) {
|
perror(__FILE__ " :: pth_msgport_put"); exit(-2); }
|
perror(__FILE__ " :: pth_msgport_put"); exit(-2); }
|
/*
* We should never get here -- there aren't any other possible
* message types.
*/
|
/*
* We should never get here -- there aren't any other possible
* message types.
*/
|
} else { printf("ERROR: unknown message action in depot()\n"); exit(-2);
|
} else { printf("ERROR: unknown message action in depot()\n"); exit(-2);
|
Line 186 |
Line 175 |
return (void *)NULL; }
|
return (void *)NULL; }
|