You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@hyperreal.org on 1999/02/03 18:50:15 UTC
cvs commit: apache-apr/pthreads/src/os/unix multithread.c
rbb 99/02/03 09:50:15
Modified: pthreads/src/main Makefile.tmpl alloc.c http_main.c
pthreads/src/modules/standard mod_autoindex.c
pthreads/src/os/unix multithread.c
Added: pthreads/src/include fdqueue.h
pthreads/src/main fdqueue.c
Log:
Port to hybrid process/thread model. Doesn't work fully, but it will serve one request before dying. Basically the process that serves the first request becomes a zombie, so the subsequent requests are never picked up off the fd queue.
Submitted by: fdqueue.[ch] submitted by Manoj KAsichainula
Revision Changes Path
1.1 apache-apr/pthreads/src/include/fdqueue.h
Index: fdqueue.h
===================================================================
#ifndef FDQUEUE_H
#define FDQUEUE_H
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
/* Bleccch. 0 on success always rubbed me the wrong way */
/* All failures are unrecoverable */
#define FD_QUEUE_SUCCESS 0
#define FD_QUEUE_FAILURE -1 /* Needs to be an invalid file descriptor because
of queue_pop semantics */
typedef struct fd_queue_elem {
int fd;
struct sockaddr addr;
} FDQueueElement;
typedef struct fd_queue {
int head;
int tail;
FDQueueElement *data;
int bounds;
pthread_mutex_t one_big_mutex;
pthread_cond_t not_empty;
pthread_cond_t not_full;
} FDQueue;
int queue_init(FDQueue *queue, size_t bounds);
void queue_destroy(FDQueue *queue);
int queue_push(FDQueue *queue, int fd, struct sockaddr *addr);
int queue_pop(FDQueue *queue, struct sockaddr *addr);
int queue_size(FDQueue *queue);
#endif /* FDQUEUE_H */
1.2 +1 -1 apache-apr/pthreads/src/main/Makefile.tmpl
Index: Makefile.tmpl
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/main/Makefile.tmpl,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.tmpl 1999/01/21 23:08:32 1.1
+++ Makefile.tmpl 1999/02/03 17:50:08 1.2
@@ -11,7 +11,7 @@
http_config.o http_core.o http_log.o \
http_main.o http_protocol.o http_request.o http_vhost.o \
util.o util_date.o util_script.o util_uri.o util_md5.o \
- md5c.o rfc1413.o
+ md5c.o rfc1413.o fdqueue.o
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $<
1.2 +7 -7 apache-apr/pthreads/src/main/alloc.c
Index: alloc.c
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/main/alloc.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- alloc.c 1999/01/21 23:08:32 1.1
+++ alloc.c 1999/02/03 17:50:09 1.2
@@ -1975,14 +1975,14 @@
if (pipe_in) {
close(in_fds[0]);
close(in_fds[1]);
- }
+ }
if (pipe_out) {
close(out_fds[0]);
close(out_fds[1]);
- }
+ }
errno = save_errno;
return 0;
- }
+ }
#ifdef WIN32
@@ -2077,10 +2077,10 @@
close(out_fds[0]);
close(out_fds[1]);
}
- if (pipe_err) {
+ if (pipe_err) {
close(err_fds[0]);
close(err_fds[1]);
- }
+ }
errno = save_errno;
return 0;
}
@@ -2101,11 +2101,11 @@
close(in_fds[0]);
}
- if (pipe_err) {
+ if (pipe_err) {
close(err_fds[0]);
dup2(err_fds[1], STDERR_FILENO);
close(err_fds[1]);
- }
+ }
/* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */
signal(SIGCHLD, SIG_DFL); /* Was that it? */
1.5 +272 -157 apache-apr/pthreads/src/main/http_main.c
Index: http_main.c
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- http_main.c 1999/01/28 21:54:07 1.4
+++ http_main.c 1999/02/03 17:50:09 1.5
@@ -92,9 +92,16 @@
#include "util_script.h" /* to force util_script.c linking */
#include "util_uri.h"
#include "scoreboard.h"
+#include "fdqueue.h"
#include <poll.h>
#include <netinet/tcp.h>
#include <stdio.h>
+
+#ifdef USE_SHMGET_SCOREBOARD
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
#include "pthread.h"
/*#include initialization if any
@@ -149,7 +156,7 @@
#ifdef MULTIPLE_GROUPS
gid_t group_id_list[NGROUPS_MAX];
#endif
-int ap_threads_per_child;
+int ap_threads_per_child = 5; /* Need to require this directive, or make a valid default */
int ap_excess_requests_per_child;
char *ap_pid_fname;
char *ap_scoreboard_fname;
@@ -199,16 +206,14 @@
array_header *ap_server_pre_read_config;
array_header *ap_server_post_read_config;
array_header *ap_server_config_defines;
+pool *pchild; /* Pool for httpd child stuff */
+
+/* The queue of sockets we've accepted */
+static FDQueue csd_queue;
/* stuff that needs thread local store in main */
typedef struct {
-
-
-
jmp_buf thread_exit;
- pool *pchild; /* Pool for httpd child stuff */
- int my_child_num;
- int requests_this_child;
int generation;
} tls_main_t;
@@ -230,7 +235,6 @@
/* used by accept_loop(), which is serialized */
-static pthread_mutex_t accept_loop_lock; /* Replace AcceptLoopLock with abstract type */
static listen_rec *head_listener;
/* *Non*-shared http_main globals... */
@@ -274,10 +278,11 @@
static pool *ptemp; /* Pool for temporart config stuff */
static pool *pcommands; /* Pool for -C and -c switches */
-scoreboard *ap_scoreboard_image = NULL;
+static int my_pid; /* for hybridization, we need this. Stupid to
+ call getpid all the time */
+static int requests_this_child;
-
-
+scoreboard *ap_scoreboard_image = NULL;
/*
* Pieces for managing the contents of the Server response header
@@ -306,6 +311,101 @@
return (server_version ? server_version : SERVER_BASEVERSION);
}
+#if defined(USE_SHMGET_SCOREBOARD)
+static key_t shmkey = IPC_PRIVATE;
+static int shmid = -1;
+
+static void setup_shared_mem(pool *p)
+{
+ struct shmid_ds shmbuf;
+#ifdef MOVEBREAK
+ char *obrk;
+#endif
+
+ if ((shmid = shmget(shmkey, SCOREBOARD_SIZE, IPC_CREAT | SHM_R | SHM_W)) ==
+-1) {
+#ifdef LINUX
+ if (errno == ENOSYS) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf,
+ "Your kernel was built without CONFIG_SYSVIPC\n"
+ "%s: Please consult the Apache FAQ for details",
+ ap_server_argv0);
+ }
+#endif
+ ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
+ "could not call shmget");
+ exit(APEXIT_INIT);
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf,
+ "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
+ * limits the use of malloc/sbrk in the program since sbrk will
+ * 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
+ */
+ if ((obrk = sbrk(MOVEBREAK)) == (char *) -1) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+ "sbrk() could not move break");
+ }
+#endif
+
+#define BADSHMAT ((scoreboard *)(-1))
+ if ((ap_scoreboard_image = (scoreboard *) shmat(shmid, 0, 0)) == BADSHMAT) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, "shmat error");
+ /*
+ * We exit below, after we try to remove the segment
+ */
+ }
+ else { /* only worry about permissions if we attached t
+he segment */
+ if (shmctl(shmid, IPC_STAT, &shmbuf) != 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+ "shmctl() could not stat segment #%d", shmid);
+ }
+ else {
+ shmbuf.shm_perm.uid = ap_user_id;
+ shmbuf.shm_perm.gid = ap_group_id;
+ if (shmctl(shmid, IPC_SET, &shmbuf) != 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+ "shmctl() could not set segment #%d", shmid);
+ }
+ }
+ }
+ /*
+ * We must avoid leaving segments in the kernel's
+ * (small) tables.
+ */
+ if (shmctl(shmid, IPC_RMID, NULL) != 0) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf,
+ "shmctl: IPC_RMID: could not remove shared memory segment #%d",
+ shmid);
+ }
+ if (ap_scoreboard_image == BADSHMAT) /* now bailout */
+ exit(APEXIT_INIT);
+
+#ifdef MOVEBREAK
+ if (obrk == (char *) -1)
+ return; /* nothing else to do */
+ if (sbrk(-(MOVEBREAK)) == (char *) -1) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+ "sbrk() could not move break back");
+ }
+#endif
+ /* ap_scoreboard_image->global.running_generation = 0;*/
+}
+
+static void reopen_scoreboard(pool *p)
+{
+}
+#endif
+
API_EXPORT(void) ap_add_version_component(const char *component)
{
if (! version_locked) {
@@ -351,13 +451,13 @@
}
}
-/* a clean exit from a child with proper cleanup */
-static void clean_child_exit(int code) __attribute__ ((noreturn));
+/* a clean exit from a child with proper cleanup
+ static void clean_child_exit(int code) __attribute__ ((noreturn)); */
static void clean_child_exit(int code)
{
- if (tls()->pchild) {
- ap_child_exit_modules(tls()->pchild, server_conf);
- ap_destroy_pool(tls()->pchild);
+ if (pchild) {
+ ap_child_exit_modules(pchild, server_conf);
+ ap_destroy_pool(pchild);
}
/* longjump(tls()->thread_exit, 1); */
}
@@ -1148,8 +1248,6 @@
break;
lr = lr->next;
}
- /* turn the list into a ring */
- lr->next = ap_listeners;
close_unused_listeners();
listenfds = ap_palloc(p, sizeof(struct pollfd));
@@ -1332,66 +1430,10 @@
/* ZZZ doesn't really make sense in a threaded server. */
}
-static int accept_loop(struct sockaddr *sa_client) /* ZZZZ */
-{
- int srv;
- listen_rec *lr;
- int sd; /* filedesc */
- int csd = 0; /* filedesc */
- ulong len = sizeof(struct sockaddr);
-
- pthread_mutex_lock(&accept_loop_lock);
- for(;;) {
- if (num_listenfds > 1) {
- /* more than one socket */
-
- srv = poll(listenfds, num_listenfds, -1); /* INF_TIMEOUT */
- if (srv < 0) {
- pthread_mutex_unlock(&accept_loop_lock);
- ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "select: (listen)");
- clean_child_exit(1);
- }
-
- if (srv == 0)
- continue;
-
- /* find a listner */
- lr = head_listener;
- do {
- /* XXX: should we check for poll error? */
- if (listenfds[lr->index].revents & POLLIN) { /* ready to read?*/
- /* advance to the next listner for next loop */
- head_listener = lr->next;
- goto got_ir;
- }
- lr = lr->next;
- } while (lr != head_listener);
- /* if we don;t find anything then just start again */
- continue;
-
-got_ir:
- sd = lr->fd;
- }
- else {
- /* only one socket, just pretent we did the other stuff */
- sd = ap_listeners->fd;
- }
-
- csd = accept(sd, sa_client, &len);
-
- if (csd >= 0)
- break; /* We have a socket ready for reading */
-
- /* XXX: deal with error conditions... */
- }
- pthread_mutex_unlock(&accept_loop_lock);
- return csd;
-}
-
static void process_socket(pool *ptrans, struct sockaddr *sa_client, int csd, int my_child_num) /* ZZZZ */
{
- struct sockaddr sa_server; /* ZZZZ */
- ulong len = sizeof(struct sockaddr);
+ struct sockaddr sa_server; /* ZZZZ */
+ size_t len = sizeof(struct sockaddr);
BUFF *conn_io;
request_rec *r;
conn_rec *current_conn;
@@ -1469,82 +1511,153 @@
#endif
}
-static void child_main(int child_num_arg, tls_main_t *t)
+void * accept_thread(void * sd)
{
+ int csd = 0;
+ int * temp = sd;
struct sockaddr sa_client;
- pool *ptrans;
- int csd;
+ size_t len = sizeof(struct sockaddr);
- /* All of initialization is a critical section, we don't care if we're
- * told to HUP or USR1 before we're done initializing. For example,
- * we could be half way through child_init_modules() when a restart
- * signal arrives, and we'd have no real way to recover gracefully
- * and exit properly.
- *
- * I suppose a module could take forever to initialize, but that would
- * be either a broken module, or a broken configuration (i.e. network
- * problems, file locking problems, whatever). -djg
- */
+ for (;;) {
+ csd = accept(*temp, &sa_client, &len);
+ if (csd >= 0) {
+ if (queue_push(&csd_queue, csd, &sa_client) != 0) {
+ /* ap_log_error*/
+ }
+ } else{
+ /* ap_log_error()*/
+ }
+ /* thread_exit */
+ }
+}
- csd = -1;
- t->my_child_num = child_num_arg;
- t->requests_this_child = 0;
+void * worker_thread(void * dummy)
+{
+ int my_pid = *(int *)dummy;
+ struct sockaddr sa_client;
- /* Get a sub pool for global allocations in this child, so that
- * we can have cleanups occur when the child exits.
- */
- ptrans = t->pchild = ap_make_sub_pool(pconf);
+ for (;;) {
+ int csd = queue_pop(&csd_queue, &sa_client);
+ pthread_t tid = pthread_self();
+ process_socket(pchild, &sa_client, csd, my_pid);
+ }
+}
+
+static void set_group_privs(void)
+{
+#ifndef WIN32
+ if (!geteuid()) {
+ char *name;
- fprintf(stderr, "%d child_main: status ready\n", child_num_arg);
+ /* Get username if passed as a uid */
- (void) ap_update_child_status(child_num_arg, SERVER_READY, (request_rec*) NULL);
+ if (ap_user_name[0] == '#') {
+ struct passwd *ent;
+ uid_t uid = atoi(&ap_user_name[1]);
+
+ if ((ent = getpwuid(uid)) == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "getpwuid: couldn't determine user name from uid %u, "
+ "you probably need to modify the User directive",
+ (unsigned)uid);
+ clean_child_exit(APEXIT_CHILDFATAL);
+ }
- while (1) {
+ name = ent->pw_name;
+ }
+ else
+ name = ap_user_name;
- ap_clear_pool(ptrans);
+#ifndef OS2
+ /* OS/2 dosen't support groups. */
- (void) ap_update_child_status(child_num_arg, SERVER_READY, (request_rec *) NULL);
- csd = accept_loop(&sa_client);
- fprintf(stderr, "%d child main: got accept\n", child_num_arg);
- process_socket(ptrans, &sa_client, csd, child_num_arg);
-
+ /* Reset `groups' attributes. */
+
+ if (initgroups(name, ap_group_id) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "initgroups: unable to set groups for User %s "
+ "and Group %u", name, (unsigned)ap_group_id);
+ clean_child_exit(APEXIT_CHILDFATAL);
+ }
+#ifdef MULTIPLE_GROUPS
+ if (getgroups(NGROUPS_MAX, group_id_list) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "getgroups: unable to get group list");
+ clean_child_exit(APEXIT_CHILDFATAL);
+ }
+#endif
+ if (setgid(ap_group_id) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "setgid: unable to set group id to Group %u",
+ (unsigned)ap_group_id);
+ clean_child_exit(APEXIT_CHILDFATAL);
+ }
+#endif
}
+#endif /* ndef WIN32 */
}
-static tls_main_t *create_tls(void)
+static void child_main(int child_num_arg)
{
- tls_main_t *t;
- int rc;
- t = malloc(sizeof(*t));
- memset(t, 0, sizeof(*t));
- if (ap_scoreboard_image) {
- t->generation = ap_scoreboard_image->global.exit_generation;
- }
-
- rc = pthread_setspecific(tls_main_key, t);
-
- if (rc) {
- fprintf(stderr, "pthread_setspecific error\n");
- exit(1);
+ listen_rec *lr;
+ int i;
+ pthread_t thread;
+ int my_child_num = child_num_arg;
+
+
+ my_pid = getpid();
+ requests_this_child = 0;
+
+ pchild = ap_make_sub_pool(pconf);
+
+ /*stuff to do before we switch id's, so we have permissions.*/
+ reopen_scoreboard(pchild);
+ /* SAFE_ACCEPT(accept_mutex_child_init(pchild));*/
+
+ set_group_privs();
+
+ if (!geteuid() && (setuid(ap_user_id) == -1)) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "setuid: unable to change uid");
+ clean_child_exit(APEXIT_CHILDFATAL);
}
-
- return t;
-}
-static void *child_starter(void *dummy)
-{
- tls_main_t *t;
-
- t = create_tls();
- if (!setjmp(t->thread_exit)) {
- child_main((int)dummy, t);
+ ap_child_init_modules(pchild, server_conf);
+
+ /*done with init critical section */
+
+ queue_init(&csd_queue, 2);
+
+ /* Setup worker threads */
+
+ for (i=0; i < ap_threads_per_child; i++) {
+ if (pthread_create(&thread, NULL, worker_thread, &my_child_num)) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "pthread_create: unable to create worker thread");
+ exit(1);
+ } else {
+ /* UPDATE_SCOREBOARD with thread id and state */
+ }
+ }
+ /* Setup acceptor threads */
+
+ lr = ap_listeners;
+ while (lr != NULL) {
+ if (pthread_create(&thread, NULL, accept_thread, &(lr->fd))) {
+ ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+ "pthread_create: unable to create acceptor thread");
+ exit(1);
+ } else {
+ /* UPDATE_SCOREBOARD with thread id and state */
+ }
+ lr = lr->next;
}
}
static int make_child(server_rec *s, int slot, time_t now) /* ZZZ */
{
pthread_t tid; /* ZZZZ */
-
+ int pid;
int rc;
if (slot + 1 > max_daemons_limit) {
@@ -1552,19 +1665,15 @@
}
if (one_process) {
- child_main(slot, tls());
+ set_signals();
+ child_main(slot);
}
+ Explain1("Starting new child in slot %d",slot);
(void) ap_update_child_status(slot, SERVER_STARTING, (request_rec *) NULL);
-
- /*tid = CreateThread(threadtype, child_starter, (void *)slot, */
- /* priority, ????);*/
- rc = pthread_create(&tid, NULL, child_starter, (void*) slot);
-
- if (rc) {
- printf("pthread_create failed - %d\n", rc);
- ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, s, "pthread_create() failed");
+ if ((pid = fork()) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
/* fork didn't succeed. Fix the scoreboard or else
* it will say SERVER_STARTING forever and ever
@@ -1579,11 +1688,30 @@
return -1;
}
- ap_scoreboard_image->parent[slot].tid = tid;
+ if (!pid) {
+#ifdef AIX_BIND_PROCESSOR
+ /* By default, AIX binds to a single processor. This bit unbinds
+ children which will then bind to another CPU.
+ */
+#include <sys/processor.h>
+ int status = bindprocessor(BINDPROCESS, (int)getpid(),
+ PROCESSOR_CLASS_ANY);
+ if (status != OK)
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, server_conf,
+ "processor unbind failed %d", status);
+#endif
+
+ RAISE_SIGSTOP(MAKE_CHILD);
+ MONCONTROL(1);
+ set_signals();
+
+ child_main(slot);
- return 0;
-}
+ ap_scoreboard_image->parent[slot].pid = pid;
+ return 0;
+ }
+}
/* start up a bunch of children */
static void startup_children(int number_to_start)
@@ -1742,7 +1870,7 @@
pid = -1;
if (pid >= 0) {
- child_slot = find_child_by_tid(NULL);
+ child_slot = find_child_by_tid(0);
if (child_slot >= 0) {
(void) ap_update_child_status(child_slot, SERVER_DEAD,
(request_rec *) NULL);
@@ -1818,11 +1946,9 @@
reinit_scoreboard(pconf);
}
- set_signals();
- /* set up accept_loop */
+ /* set up get_socket */
head_listener = ap_listeners;
- pthread_mutex_init(&accept_loop_lock, NULL);
if (ap_daemons_max_free < ap_daemons_min_free + 1) /* Don't thrash... */
ap_daemons_max_free = ap_daemons_min_free + 1;
@@ -1906,8 +2032,6 @@
"SIGHUP received. Attempting to restart");
}
- pthread_mutex_destroy(&accept_loop_lock);
-
}
static void standalone_main(int argc, char **argv)
@@ -1941,15 +2065,6 @@
int c;
int rc; /* ZZZZ */
int configtestonly;
-
- /* Create thread local storage key */
- rc = pthread_key_create(&tls_main_key, NULL);
- if (rc) {
- perror("pthread_key_create failed\n");
- exit(1);
- }
-
- create_tls();
MONCONTROL(0); /* WTF is this? */
1.1 apache-apr/pthreads/src/main/fdqueue.c
Index: fdqueue.c
===================================================================
#include "fdqueue.h"
/* XXX - We should get rid of the malloc and free used here. This should be
* ap_palloc, I guess (mvsk) */
/* Assumption: queue itself is allocated by the user */
/* Assumption: increment and decrement are atomic on int */
int queue_init(FDQueue *queue, size_t bounds) {
pthread_mutex_init(&queue->one_big_mutex, NULL);
pthread_cond_init(&queue->not_empty, NULL);
pthread_cond_init(&queue->not_full, NULL);
queue->head = queue->tail = 0;
queue->data = malloc(bounds * sizeof(FDQueueElement));
queue->bounds = bounds;
return FD_QUEUE_SUCCESS;
}
void queue_destroy(FDQueue *queue) {
free(queue->data);
/* Ignore errors here, we can't do anything about them anyway */
pthread_cond_destroy(&queue->not_empty);
pthread_cond_destroy(&queue->not_full);
pthread_mutex_destroy(&queue->one_big_mutex);
}
int queue_push(FDQueue *queue, int fd, struct sockaddr *addr) {
if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
return FD_QUEUE_FAILURE;
}
while (queue->head == ((queue->tail + 1) % queue->bounds)) {
pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
}
queue->data[queue->tail].fd = fd;
queue->data[queue->tail].addr = *addr;
queue->tail = (queue->tail + 1) % queue->bounds;
if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
return FD_QUEUE_FAILURE;
}
if (pthread_cond_signal(&queue->not_empty) != 0)
perror("signal didn't work :(");
return FD_QUEUE_SUCCESS;
}
int queue_pop(FDQueue *queue, struct sockaddr *addr) {
int fd;
if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
return FD_QUEUE_FAILURE;
}
while (queue->head == queue->tail) {
pthread_cond_wait(&queue->not_empty, &queue->one_big_mutex);
}
fd = queue->data[queue->head].fd;
*addr = queue->data[queue->head].addr;
queue->head = (queue->head + 1) % queue->bounds;
if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
return FD_QUEUE_FAILURE;
}
pthread_cond_signal(&queue->not_full);
return fd;
}
int queue_size(FDQueue *queue) {
return ((queue->tail - queue->head + queue->bounds) % queue->bounds);
}
1.3 +2 -1 apache-apr/pthreads/src/modules/standard/mod_autoindex.c
Index: mod_autoindex.c
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_autoindex.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- mod_autoindex.c 1999/01/22 17:10:28 1.2
+++ mod_autoindex.c 1999/02/03 17:50:12 1.3
@@ -884,7 +884,8 @@
p->ascending = (ap_toupper(direction) == D_ASCENDING);
if (autoindex_opts & FANCY_INDEXING) {
- request_rec *rr = ap_sub_req_lookup_file(name, r);
+ request_rec *rr = ap_sub_req_lookup_file(name, r);
+ fprintf(stderr, "sub_req:::: %s\n", name);
if (rr->finfo.st_mode != 0) {
p->lm = rr->finfo.st_mtime;
1.3 +2 -2 apache-apr/pthreads/src/os/unix/multithread.c
Index: multithread.c
===================================================================
RCS file: /home/cvs/apache-apr/pthreads/src/os/unix/multithread.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- multithread.c 1999/01/27 16:15:49 1.2
+++ multithread.c 1999/02/03 17:50:14 1.3
@@ -37,8 +37,8 @@
if ((pid = fork()) == -1) {
return pid;
} else if (pid == 0) {
- execvp(file, argv);
- return -1;
+ if (execvp(file, argv) == -1)
+ return -1;
} else
return pid;
}