scoreboard.c revision 0942697a9b5de44865676345a3828741c827efe6
#include "httpd.h"
#include "http_log.h"
#include "http_main.h"
#include "http_core.h"
#include "http_config.h"
#include "unixd.h"
#include "http_conf_globals.h"
#include "mpmt_pthread.h"
#include "scoreboard.h"
#ifdef USE_SHMGET_SCOREBOARD
#endif
#ifdef USE_OS2_SCOREBOARD
/* Add MMAP style functionality to OS/2 */
#define INCL_DOSMEMMGR
#define INCL_DOSEXCEPTIONS
#define INCL_DOSSEMAPHORES
#include <os2.h>
#include <umalloc.h>
#include <stdio.h>
caddr_t get_shared_heap(const char *);
#endif
/*****************************************************************
*
* Dealing with the scoreboard... a lot of these variables are global
* only to avoid getting clobbered by the longjmp() that happens when
* a hard timeout expires...
*
* We begin with routines which deal with the file itself...
*/
#ifdef MULTITHREAD
/*
* In the multithreaded mode, have multiple threads - not multiple
* processes that need to talk to each other. Just use a simple
* malloc. But let the routines that follow, think that you have
* shared memory (so they use memcpy etc.)
*/
void reinit_scoreboard(ap_context_t *p)
{
if (ap_scoreboard_image == NULL) {
}
}
void cleanup_scoreboard(void)
{
}
API_EXPORT(void) ap_sync_scoreboard_image(void)
{
}
#else /* MULTITHREAD */
#if defined(USE_OS2_SCOREBOARD)
/* The next two routines are used to access shared memory under OS/2. */
/* This requires EMX v09c to be installed. */
{
void *mem;
Heap_t h;
if (rc != 0)
return NULL;
if (h == NULL)
return (caddr_t) h;
}
{
the shared memory object */
of the shared memory object */
/* Request read and write access to */
/* the shared memory object */
if (rc != 0) {
return 0;
}
return BaseAddress;
}
static void setup_shared_mem(ap_context_t *p)
{
caddr_t m;
int rc;
if (m == 0) {
}
if (rc != 0) {
"%s: Could not uopen() newly created OS/2 Shared memory pool.\n",
}
ap_scoreboard_image = (scoreboard *) m;
}
{
caddr_t m;
int rc;
if (m == 0) {
}
ap_scoreboard_image = (scoreboard *) m;
}
#elif defined(USE_POSIX_SCOREBOARD)
/*
* POSIX 1003.4 style
*
* Note 1:
* where no subdirectories allowed.
*
* POSIX shm_open() and shm_unlink() will take care about this issue,
* but to avoid confusion, I suggest to redefine scoreboard file name
* in httpd.conf to cut "logs/" from it. With default setup actual name
* will be "/dev/shmem/logs.apache_status".
*
* If something went wrong and Apache did not unlinked this object upon
* exit, you can remove it manually, using "rm -f" command.
*
* Note 2:
* does NOT support BSD style anonymous mapping. So, the order of
* conditional compilation is important:
* this #ifdef section must be ABOVE the next one (BSD style).
*
* I tested this stuff and it works fine for me, but if it provides
* trouble for you, just comment out USE_MMAP_SCOREBOARD in QNX section
* of ap_config.h
*
* June 5, 1997,
* Igor N. Kovalenko -- infoh@mail.wplus.net
*/
static void cleanup_shared_mem(void *d)
{
}
static void setup_shared_mem(ap_context_t *p)
{
char buf[512];
caddr_t m;
int fd;
if (fd == -1) {
}
}
}
ap_scoreboard_image = (scoreboard *) m;
}
{
}
#elif defined(USE_MMAP_SCOREBOARD)
static void setup_shared_mem(ap_context_t *p)
{
caddr_t m;
#if defined(MAP_ANON)
/* BSD style */
#ifdef CONVEXOS11
/*
* 9-Aug-97 - Jeff Venters (venters@convex.hp.com)
* ConvexOS maps address space as follows:
* 0x00000000 - 0x7fffffff : Kernel
* 0x80000000 - 0xffffffff : User
* Start mmapped area 1GB above start of text.
*
* Also, the length requires a pointer as the actual length is
* returned (rounded up to a page boundary).
*/
{
unsigned len = SCOREBOARD_SIZE;
}
#elif defined(MAP_TMPFILE)
{
char mfile[] = "/tmp/apache_shmem_XXXX";
if (fd == -1) {
perror("open");
}
if (m == (caddr_t) - 1) {
perror("mmap");
}
}
#else
#endif
if (m == (caddr_t) - 1) {
perror("mmap");
}
#else
/* Sun style */
int fd;
if (fd == -1) {
perror("open");
}
if (m == (caddr_t) - 1) {
perror("mmap");
}
#endif
ap_scoreboard_image = (scoreboard *) m;
}
{
}
#elif defined(USE_SHMGET_SCOREBOARD)
static int shmid = -1;
static void setup_shared_mem(ap_context_t *p)
{
#ifdef MOVEBREAK
char *obrk;
#endif
#ifdef LINUX
"Your kernel was built without CONFIG_SYSVIPC\n"
"%s: Please consult the Apache FAQ for details",
}
#endif
"could not call shmget");
}
"created shared memory segment #%d", shmid);
#ifdef MOVEBREAK
/*
* Some SysV systems place the shared segment WAY too close
* to the dynamic memory break point (sbrk(0)). This severely
* refuse to move past that point.
*
* To get around this, we move the break point "way up there",
* attach the segment and then move break back down. Ugly
*/
"sbrk() could not move break");
}
#endif
/*
* We exit below, after we try to remove the segment
*/
}
else { /* only worry about permissions if we attached the segment */
"shmctl() could not stat segment #%d", shmid);
}
else {
"shmctl() could not set segment #%d", shmid);
}
}
}
/*
* We must avoid leaving segments in the kernel's
* (small) tables.
*/
"shmctl: IPC_RMID: could not remove shared memory segment #%d",
shmid);
}
#ifdef MOVEBREAK
if (obrk == (char *) -1)
return; /* nothing else to do */
"sbrk() could not move break back");
}
#endif
}
{
}
#else
#define SCOREBOARD_FILE
static scoreboard _scoreboard_image;
static int scoreboard_fd = -1;
/* XXX: things are seriously screwed if we ever have to do a partial
* read or write ... we could get a corrupted scoreboard
*/
{
do {
if (rv > 0) {
}
}
{
do {
if (rv > 0) {
}
}
static void cleanup_scoreboard_file(void *foo)
{
}
{
if (scoreboard_fd != -1)
if (scoreboard_fd == -1) {
clean_child_exit(1);
}
}
#endif
/* Called by parent process */
void reinit_scoreboard(ap_context_t *p)
{
int running_gen = 0;
if (ap_scoreboard_image)
#ifndef SCOREBOARD_FILE
if (ap_scoreboard_image == NULL) {
setup_shared_mem(p);
}
#else
if (scoreboard_fd == -1) {
}
#endif
}
/* Routines called to deal with the scoreboard image
* --- note that we do *not* need write locks, since update_child_status
* only updates a *single* record in place, and only one process writes to
* a given scoreboard slot at a time (either the child process owning that
* slot, or the parent, noting that the child has died).
*
* As a final note --- setting the score entry to getpid() is always safe,
* since when the parent is writing an entry, it's only noting SERVER_DEAD
* anyway.
*/
ap_inline void ap_sync_scoreboard_image(void)
{
#ifdef SCOREBOARD_FILE
lseek(scoreboard_fd, 0L, 0);
#endif
}
#endif /* MULTITHREAD */
API_EXPORT(int) ap_exists_scoreboard_image(void)
{
return (ap_scoreboard_image ? 1 : 0);
}
{
/* XXX - needs to be fixed to account for threads */
#ifdef SCOREBOARD_FILE
#endif
}
void update_scoreboard_global(void)
{
#ifdef SCOREBOARD_FILE
sizeof ap_scoreboard_image->global);
#endif
}
{
long int bs = 0;
if (r->sent_bodyct)
#ifndef NO_TIMES
#endif
ss->access_count++;
ss->my_access_count++;
ss->conn_count++;
}
{
int i;
int max_daemons_limit = ap_get_max_daemons();
for (i = 0; i < max_daemons_limit; ++i)
return i;
return -1;
}
{
int old_status;
if (child_num < 0)
return -1;
&& old_status == SERVER_STARTING) {
}
if (ap_extended_status) {
/*
* Reset individual counters
*/
if (status == SERVER_DEAD) {
ss->my_access_count = 0L;
ss->my_bytes_served = 0L;
}
ss->conn_count = (unsigned short) 0;
ss->conn_bytes = (unsigned long) 0;
}
if (r) {
conn_rec *c = r->connection;
if (r->the_request == NULL) {
} else {
/* Don't reveal the password in the server-status view */
}
}
}
return old_status;
}
{
if (child_num < 0)
return;
if (status == START_PREQUEST) {
/*ss->start_time = GetCurrentTime(); ZZZ return time in uS since the
epoch. Some platforms do not support gettimeofday. Create a routine
to get the current time is some useful units. */
}
}
else if (status == STOP_PREQUEST) {
/*ss->stop_time = GetCurrentTime();
ZZZ return time in uS since the epoch */
}
}
}
/* Stub functions until this MPM supports the connection status API */
const char *value)
{
/* NOP */
}
{
/* NOP */
}