added event handler

Wed, 16 May 2012 12:47:28 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 16 May 2012 12:47:28 +0200
changeset 29
e8619defde14
parent 28
f387669912e8
child 30
27c7511c0e34

added event handler

src/server/Makefile file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/event.h file | annotate | diff | comparison | revisions
src/server/daemon/event_solaris.c file | annotate | diff | comparison | revisions
src/server/daemon/event_solaris.h file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/objs.mk file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
src/server/util/ereport.h file | annotate | diff | comparison | revisions
src/server/util/pool.c file | annotate | diff | comparison | revisions
src/server/util/system.c file | annotate | diff | comparison | revisions
src/server/util/systhr.c file | annotate | diff | comparison | revisions
src/server/util/systhr.h file | annotate | diff | comparison | revisions
src/server/webdav/davparser.cpp file | annotate | diff | comparison | revisions
src/server/webdav/davparser.h file | annotate | diff | comparison | revisions
src/server/webdav/saxhandler.cpp file | annotate | diff | comparison | revisions
src/server/webdav/saxhandler.h file | annotate | diff | comparison | revisions
src/server/webdav/webdav.c file | annotate | diff | comparison | revisions
src/server/webdav/webdav.h file | annotate | diff | comparison | revisions
--- a/src/server/Makefile	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/Makefile	Wed May 16 12:47:28 2012 +0200
@@ -27,6 +27,7 @@
 #
 
 BUILD_ROOT = ../../
+include $(BUILD_ROOT)conf.mk
 
 CFLAGS  =
 
--- a/src/server/daemon/config.c	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/daemon/config.c	Wed May 16 12:47:28 2012 +0200
@@ -112,13 +112,33 @@
     serverconfig->listeners = NULL;
     serverconfig->host_vs = ucx_map_new(16);
     // TODO: init serverconfig stuff
-
+    
+    /* init logfile first */
+    UcxList *lfl= ucx_map_sstr_get(serverconf->objects, sstrn("LogFile", 7));
+    if(lfl != NULL) {
+        ServerConfigObject *logobj = lfl->data;
+        if(logobj == NULL) {
+            /* error */
+            return NULL;
+        }
+        
+        int ret = cfg_handle_logfile(serverconfig, logobj);
+        if(ret != 0) {
+            /* cannot initialize log file */
+            return NULL;
+        }
+    } else {
+        /* horrible error */
+        return NULL;
+    }
+    
     /* convert ServerConfig to ServerConfiguration */
     for(int i=0;i<serverconf->objects->size;i++) {
         UcxMapElement *elm = &serverconf->objects->map[i];
         while(elm != NULL) {
             UcxList *list = elm->data;
             while(list != NULL) {
+
                 ServerConfigObject *scfgobj = list->data;
 
                 /* handle config object */
@@ -126,7 +146,7 @@
                 if(!sstrcmp(scfgobj->type, sstr("Runtime"))) {
                     hr = cfg_handle_runtime(serverconfig, scfgobj);
                 } else if(!sstrcmp(scfgobj->type, sstr("LogFile"))) {
-                    hr = cfg_handle_logfile(serverconfig, scfgobj);
+                    //hr = cfg_handle_logfile(serverconfig, scfgobj);
                 } else if(!sstrcmp(scfgobj->type, sstr("AuthDB"))) {
                     hr = cfg_handle_authdb(serverconfig, scfgobj);
                 } else if(!sstrcmp(scfgobj->type, sstr("Listener"))) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/event.h	Wed May 16 12:47:28 2012 +0200
@@ -0,0 +1,66 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EVENT_H
+#define	EVENT_H
+
+#include "../public/nsapi.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+    
+typedef struct event_handler event_handler_t;
+typedef struct event         event_t;
+
+typedef void(*event_func)(event_handler_t*, event_t*);
+
+struct event {
+    pblock       *pb;
+    Session      *sn;
+    Request      *rq;
+    event_func   fn;
+    intptr_t     object;
+    void         *cookie;
+};
+
+event_handler_t* evhandler_create(int numthreads);
+
+int ev_pollin(event_handler_t *h, int fd, event_t *event);
+
+int ev_pollout(event_handler_t *h, int fd, event_t *event);
+
+int evt_send(event_handler_t *h, event_t *event);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* EVENT_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/event_solaris.c	Wed May 16 12:47:28 2012 +0200
@@ -0,0 +1,138 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <atomic.h>
+
+#include "event_solaris.h"
+
+event_handler_t* evhandler_create(int numthreads) {
+    event_handler_t *ev = malloc(sizeof(event_handler_t));
+    if(ev == NULL) {
+        return NULL;
+    }
+    
+    ev->ports = calloc(numthreads, sizeof(int));
+    if(ev->ports == NULL) {
+        free(ev);
+        return NULL;
+    }
+    ev->nports = numthreads;
+    ev->lp = 0;
+    
+    /* create ports event threads */
+    for(int i=0;i<numthreads;i++) {
+        /* create port */
+        ev->ports[i] = port_create();
+        if(ev->ports[i] == 0) {
+            free(ev->ports);
+            free(ev);
+            return NULL;
+        }
+        
+        /*
+         * start a new handler thread
+         * the thread needs the event port and a pointer to the event handler
+         */
+        ev_thr_conf_t *conf = malloc(sizeof(ev_thr_conf_t));
+        if(conf == NULL) {
+            free(ev->ports);
+            free(ev);
+            return NULL;
+        }
+        conf->handler = ev;
+        conf->port = ev->ports[i];
+        
+        systhread_start(0, 0, (thrstartfunc)ev_handle_events, ev);
+        /* TODO: error handling */
+    }
+    
+    return ev;
+}
+
+void ev_handle_events(ev_thr_conf_t *conf) {
+    event_handler_t *ev = conf->handler;
+    int port = conf->port;
+    
+    free(conf);
+    
+    port_event_t events[16];
+    struct timespec timeout;
+    timeout.tv_nsec = 0;
+    timeout.tv_sec = 600;
+    
+    for(;;) {
+        /* wait for events */
+        uint_t nev = 1;
+        int ret = port_getn(port, events, 16, &nev, &timeout);
+        if(ret == -1) {
+            /* TODO: check for error */
+            continue;
+        }
+        
+        for(int i=0;i<nev;i++) {
+            event_t *event = events[i]->portev_user;
+            if(event->fn) {
+                event->fn(ev, event);
+            }
+        }
+    }
+}
+
+/* returns a event handler port */
+int ev_get_port(event_handler_t *h) {
+    int cp = h->lp % h->nports;
+    atomic_inc_32(&h->lp);
+    return cp;
+}
+
+int ev_pollin(event_handler_t *h, int fd, event_t *event) {
+    event->object = (intptr_t)fd;
+    return port_associate(
+            ev_get_port(h),
+            PORT_SOURCE_FD,
+            (uintptr_t)fd,
+            POLLIN,
+            event);
+}
+
+int ev_pollout(event_handler_t *h, int fd, event_t *event) {
+    event->object = (intptr_t)fd;
+    return port_associate(
+            ev_get_port(h),
+            PORT_SOURCE_FD,
+            (uintptr_t)fd,
+            POLLOUT,
+            event);
+}
+
+int evt_send(event_handler_t *h, event_t *event) {
+    event->object = 0;
+    return port_send(ev_get_port(h), 0, event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/event_solaris.h	Wed May 16 12:47:28 2012 +0200
@@ -0,0 +1,63 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EVENT_SOLARIS_H
+#define	EVENT_SOLARIS_H
+
+#include "event.h"
+#include "../util/systhr.h"
+
+#include <port.h>
+#include <aio.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct event_handler {
+    int       *ports;
+    uint32_t  nports;
+    uint32_t  lp;
+};
+
+typedef struct ev_thr_conf {
+    event_handler_t *handler;
+    int             port;
+} ev_thr_conf_t;
+
+void ev_handle_events(ev_thr_conf_t *conf);
+
+int ev_get_port(event_handler_t *h);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* EVENT_SOLARIS_H */
+
--- a/src/server/daemon/httplistener.c	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/daemon/httplistener.c	Wed May 16 12:47:28 2012 +0200
@@ -51,6 +51,7 @@
 
 #include "session.h"
 #include "configmanager.h"
+#include "log.h"
 
 UcxMap *listener_map = NULL;
 
@@ -81,6 +82,7 @@
     listener->name = conf->name;
     listener->session_handler = create_basic_session_handler();
     listener->nacceptors = conf->nacceptors;
+    listener->port = conf->port;
     ucx_map_sstr_put(listener_map, listener->name, listener);
 
     struct sockaddr_in servaddr;   /* server address */
@@ -122,6 +124,7 @@
 
 int http_listener_start(HttpListener *listener) {
     printf("INFO: start listener\n");
+    log_ereport(LOG_LEVEL_INFO, "start listener on port %d", listener->port);
 
     if (listen(listener->server_socket, 256) == -1) {
         perror("Error: http_listener_start: listen");
--- a/src/server/daemon/objs.mk	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/daemon/objs.mk	Wed May 16 12:47:28 2012 +0200
@@ -46,6 +46,10 @@
 DAEMONOBJ += configmanager.o
 DAEMONOBJ += log.o
 
+#ifeq ($(OS), SunOS)
+DAEMONOBJ += event_solaris.o
+#endif
+
 DAEMONOBJS = $(DAEMONOBJ:%=$(DMN_OBJPRE)%)
 DAEMONSOURCE = $(DAEMONOBJ:%.o=daemon/%.c)
 
--- a/src/server/public/nsapi.h	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/public/nsapi.h	Wed May 16 12:47:28 2012 +0200
@@ -349,6 +349,7 @@
 #include <unistd.h>
 #include <sys/file.h>
 #include <alloca.h> /* new */
+#include <pthread.h>
 #ifndef HPUX
 #include <sys/select.h>
 #endif
@@ -830,7 +831,8 @@
 };
 
 /* Define a handle for a thread */
-typedef void* SYS_THREAD;
+//typedef void* SYS_THREAD;
+typedef pthread_t SYS_THREAD;
 
 /* Define an error value for the thread handle */
 #define SYS_THREAD_ERROR NULL
--- a/src/server/util/ereport.h	Sun May 06 10:09:27 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- *
- * THE BSD LICENSE
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer. 
- * Redistributions in binary form must reproduce the above copyright notice, 
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 
- *
- * Neither the name of the  nor the names of its contributors may be
- * used to endorse or promote products derived from this software without 
- * specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BASE_EREPORT_H
-#define BASE_EREPORT_H
-
-#ifndef NOINTNSAPI
-#define INTNSAPI
-#endif /* !NOINTNSAPI */
-
-/*
- * ereport.h: Records transactions, reports errors to administrators, etc.
- * 
- * Rob McCool
- */
-
-//TODO: include netsite.h or systems.h
-
-#ifndef BASE_SESSION_H
-#include "../daemon/session.h"
-#endif /* !BASE_SESSION_H */
-
-/* Pseudo-filename to enable logging to syslog */
-#define EREPORT_SYSLOG "SYSLOG"
-
-/* NSAPI degrees used by Java but not exposed in nsapi.h */
-#define LOG_FINER  7
-#define LOG_FINEST 8
-
-/* --- Begin function prototypes --- */
-
-#ifdef INTNSAPI
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/*
- * INTereport logs an error of the given degree and formats the arguments with 
- * the printf() style fmt. Returns whether the log was successful. Records 
- * the current date.
- */
-
-NSAPI_PUBLIC int INTereport(int degree, const char *fmt, ...);
-NSAPI_PUBLIC int INTereport_v(int degree, const char *fmt, va_list args);
-
-/*
- * INTereport_init initializes the error logging subsystem and opens the static
- * file descriptors. It returns NULL upon success and an error string upon
- * error. If a userpw is given, the logs will be chowned to that user.
- */
-
-NSAPI_PUBLIC
-char *INTereport_init(const char *err_fn, const char *email, struct passwd *pwuser, const char *version, int restarted);
-
-NSAPI_PUBLIC void INTereport_terminate(void);
-
-/* For restarts */
-NSAPI_PUBLIC SYS_FILE INTereport_getfd(void);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#ifdef __cplusplus
-class EreportableException;
-NSAPI_PUBLIC int INTereport_exception(const EreportableException& e);
-#endif
-
-/* --- End function prototypes --- */
-
-#define ereport INTereport
-#define ereport_v INTereport_v
-#define ereport_init INTereport_init
-#define ereport_terminate INTereport_terminate
-#define ereport_getfd INTereport_getfd
-#define ereport_exception INTereport_exception
-
-typedef int (EreportFunc)(const VirtualServer* vs, int degree, const char *formatted, int formattedlen, const char *raw, int rawlen, void *data);
-
-void ereport_set_servername(const char* name);
-void ereport_set_logvsid(PRBool b);
-void ereport_set_logall(PRBool b);
-void ereport_set_alwaysreopen(PRBool b);
-void ereport_set_timefmt(const char* timeFmt);
-void ereport_set_degree(int degree);
-int ereport_level2degree(const char *level, int defdegree);
-PRBool ereport_can_log(int degree);
-int ereport_request(Request* rq, int degree, const char *fmt, ...);
-char *ereport_abs_filename(const char *filename);
-void ereport_rotate(const char* ext);
-void ereport_set_rotate_callback(void (*fn)(const char* filenameNew, const char* filenameOld));
-void ereport_reopen(void);
-void ereport_outofmemory(void);
-void ereport_disaster(int degree, const char *fmt, ...);
-NSAPI_PUBLIC int ereport_register_cb(EreportFunc* ereport_func, void* data);
-NSAPI_PUBLIC int ereport_register_thread_cb(EreportFunc* ereport_func, void* data);
-
-#endif /* INTNSAPI */
-
-#endif /* !BASE_EREPORT_H */
--- a/src/server/util/pool.c	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/util/pool.c	Wed May 16 12:47:28 2012 +0200
@@ -52,7 +52,7 @@
 //include "systems.h"
 #include "systhr.h"
 #include "pool_pvt.h"
-#include "ereport.h"
+//include "ereport.h"
 //include "base/session.h"
 //include "frame/req.h"
 //include "frame/http.h"
@@ -154,7 +154,7 @@
         //        XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_));
         PERM_FREE(newblock);
         PERM_FREE(newdata);
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         return NULL;
     }
     newblock->data = newdata;
@@ -257,7 +257,7 @@
         if (newpool->curr_block == NULL) {
             //ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_));
             pool_destroy((pool_handle_t *)newpool);
-            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
             return NULL;
         }
 
@@ -274,7 +274,7 @@
     }
     else {
         //ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_1));
-        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
     }
 
     return (pool_handle_t *)newpool;
@@ -531,7 +531,7 @@
         if (curr_block == NULL) {
             //ereport(LOG_CATASTROPHE,
             //        XP_GetAdminStr(DBT_poolMallocOutOfMemory_));
-            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            //PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
             return NULL;
         }
 
--- a/src/server/util/system.c	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/util/system.c	Wed May 16 12:47:28 2012 +0200
@@ -44,7 +44,7 @@
 //include <new.h>
 #endif
 #include "../daemon/netsite.h"
-#include "ereport.h"
+//include "ereport.h"
 
 #ifdef XP_WIN32
 #include <windows.h>
--- a/src/server/util/systhr.c	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/util/systhr.c	Wed May 16 12:47:28 2012 +0200
@@ -39,7 +39,7 @@
 
 
 #include "systhr.h"
-#include "ereport.h"
+//include "ereport.h"
 
 #include "prinit.h"
 #include "prthread.h"
@@ -51,16 +51,6 @@
 #include <poll.h>
 #endif
 
-#ifdef THREAD_WIN32
-#include <process.h>
-
-typedef struct {
-    HANDLE hand;
-    DWORD id;
-} sys_thread_s;
-
-#endif
-
 #define DEFAULT_STACKSIZE (64*1024)
 
 static unsigned long _systhr_stacksize = DEFAULT_STACKSIZE;
@@ -71,66 +61,62 @@
 	_systhr_stacksize = size;
 }
 
-NSAPI_PUBLIC 
-SYS_THREAD systhread_start(int prio, int stksz, thrstartfunc fn, void *arg)
-{
-    PRThread *ret = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))fn,
-				    (void *)arg, (PRThreadPriority)prio, 
-				    PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
-                                    stksz ? stksz : _systhr_stacksize);
-    return (void *) ret;
-}
 
 
-NSAPI_PUBLIC SYS_THREAD systhread_current(void)
-{
-    return PR_GetCurrentThread();
+SYS_THREAD systhread_start(int prio, int stksz, thrstartfunc fn, void *arg) {
+    pthread_t      thr = 0;
+    pthread_attr_t attr;
+    
+    pthread_attr_init(&attr);
+    if(stksz) {
+        pthread_attr_setstacksize(&attr, stksz);
+    }
+    
+    if(pthread_create(&thr, &attr, (posix_thrstartfunc)fn, arg) != 0) {
+        /* error */
+    }
+    
+    return thr;
 }
 
-NSAPI_PUBLIC void systhread_yield(void)
-{
-    PR_Sleep(PR_INTERVAL_NO_WAIT);
+SYS_THREAD systhread_current(void) {
+    return pthread_self();
 }
 
-
-NSAPI_PUBLIC void systhread_timerset(int usec)
+void systhread_yield(void)
 {
-   /* This is an interesting problem.  If you ever do turn on interrupts
-    * on the server, you're in for lots of fun with NSPR Threads
-   PR_StartEvents(usec); */
+    sched_yield();
 }
 
 
-NSAPI_PUBLIC 
+void systhread_timerset(int usec)
+{
+   
+}
+
 SYS_THREAD systhread_attach(void)
 {
-    PRThread *ret;
-    ret = PR_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL);
-
-    return (void *) ret;
+    /* TODO: what to do? */
+    return 0;
 }
 
-NSAPI_PUBLIC
 void systhread_detach(SYS_THREAD thr)
 {
-    /* XXXMB - this is not correct! */
-    PR_DetachThread();
+    pthread_detach(thr);
 }
 
-NSAPI_PUBLIC void systhread_terminate(SYS_THREAD thr)
+void systhread_terminate(SYS_THREAD thr)
 {
-    PR_Interrupt((PRThread *)thr);
+    //PR_Interrupt((PRThread *)thr);
 }
 
-NSAPI_PUBLIC void systhread_sleep(int milliseconds)
+void systhread_sleep(int msec)
 {
-#ifdef XP_WIN32
-    PR_Sleep(PR_MillisecondsToInterval(milliseconds));
-#else
-    /* poll() is more efficient than PR_Sleep() */
-    if (milliseconds > 0)
-        poll(NULL, NULL, milliseconds);
-#endif
+    if(msec > 0) {
+        poll(NULL, NULL, msec);
+    } else {
+        sched_yield();
+    }
 }
 
 NSAPI_PUBLIC void systhread_init(char *name)
@@ -158,6 +144,9 @@
     // </WORKAROUND>
 }
 
+/*
+ *  TODO: reimplement with pthread api
+ */
 
 NSAPI_PUBLIC int systhread_newkey()
 {
--- a/src/server/util/systhr.h	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/util/systhr.h	Wed May 16 12:47:28 2012 +0200
@@ -62,6 +62,8 @@
 extern "C" {
 #endif
 
+typedef void* (*posix_thrstartfunc)(void *);
+    
 NSAPI_PUBLIC
 SYS_THREAD INTsysthread_start(int prio, int stksz, thrstartfunc fn, void *arg);
 
@@ -75,7 +77,7 @@
 
 NSAPI_PUBLIC void INTsysthread_terminate(SYS_THREAD thr);
 
-NSAPI_PUBLIC void INTsysthread_sleep(int milliseconds);
+NSAPI_PUBLIC void INTsysthread_sleep(int msec);
 
 NSAPI_PUBLIC void INTsysthread_init(char *name);
 
--- a/src/server/webdav/davparser.cpp	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/webdav/davparser.cpp	Wed May 16 12:47:28 2012 +0200
@@ -90,3 +90,50 @@
 
     return davrq;
 }
+
+ProppatchRequest* dav_parse_proppatch(
+        Session *sn,
+        Request *rq,
+        char *xml,
+        size_t len)
+{
+    if(!xcinit) {
+        /* TODO: create webdav module init function */
+        XMLPlatformUtils::Initialize();
+        xcinit = 1;
+    }
+    ProppatchRequest *davrq = (ProppatchRequest*)pool_malloc(
+            sn->pool,
+            sizeof(PropfindRequest));
+    
+    
+    
+    // create xml parser
+    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
+    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
+
+    ProppatchHandler handler(davrq, sn->pool);
+    parser->setContentHandler(&handler);
+    parser->setErrorHandler(&handler);
+
+    MemBufInputSource source((XMLByte*)xml, (XMLSize_t)len, "wsid");
+    try {
+        parser->parse(source);
+    }
+    catch (const XMLException& e) {
+        printf("XMLException\n");
+        
+    }
+    catch (const SAXParseException& e) {
+        printf("SAXParseException\n");
+        
+    }
+    catch (...) {
+        printf("davaparser Exception\n");
+    }
+
+    
+    
+
+    return davrq;
+}
--- a/src/server/webdav/davparser.h	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/webdav/davparser.h	Wed May 16 12:47:28 2012 +0200
@@ -45,6 +45,12 @@
         char *xml,
         size_t len);
 
+ProppatchRequest* dav_parse_proppatch(
+        Session *sn,
+        Request *rq,
+        char *xml,
+        size_t len);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/webdav/saxhandler.cpp	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/webdav/saxhandler.cpp	Wed May 16 12:47:28 2012 +0200
@@ -126,3 +126,71 @@
 
 }
 
+
+/************* PropPatch Handler **************/
+
+ProppatchHandler::ProppatchHandler(ProppatchRequest *rq, pool_handle_t *p) {
+    davrq = rq;
+    pool  = p;
+}
+
+ProppatchHandler::~ProppatchHandler() {
+    
+}
+
+void ProppatchHandler::startElement(
+        const XMLCh *const uri,
+        const XMLCh* const localname,
+        const XMLCh* const qname,
+        const Attributes& attrs)
+{
+    char *ns  = XMLString::transcode(uri);
+    char *name = XMLString::transcode(localname);
+    
+    if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
+        davPropTag = true;
+    } else if(davPropTag) {
+        
+    }
+
+    XMLString::release(&ns);
+    XMLString::release(&name);
+}
+
+
+void ProppatchHandler::endElement(
+        const XMLCh* const   uri,
+        const XMLCh* const   localname,
+        const XMLCh* const   qname)
+{
+    char *ns  = XMLString::transcode(uri);
+    char *name = XMLString::transcode(localname);
+
+    if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) {
+        updateMode = 0;
+    } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) {
+        updateMode = 1;
+    } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
+        
+    }
+    
+
+    XMLString::release(&ns);
+    XMLString::release(&name);
+}
+
+void ProppatchHandler::characters(
+        const XMLCh *const chars,
+        const XMLSize_t length)
+{
+    
+}
+
+void ProppatchHandler::startDocument() {
+    
+}
+
+void ProppatchHandler::endDocument() {
+
+}
+
--- a/src/server/webdav/saxhandler.h	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/webdav/saxhandler.h	Wed May 16 12:47:28 2012 +0200
@@ -50,7 +50,7 @@
         const XMLCh* const   uri,
         const XMLCh* const   localname,
         const XMLCh* const   qname);
-
+    
     void startDocument();
 
     void endDocument();
@@ -63,5 +63,39 @@
     DavProperty     *property;
 };
 
+
+class ProppatchHandler : public DefaultHandler {
+public:
+    ProppatchHandler(ProppatchRequest *rq, pool_handle_t *p);
+    virtual ~ProppatchHandler();
+
+    void startElement(
+        const XMLCh* const   uri,
+        const XMLCh* const   localname,
+        const XMLCh* const   qname,
+        const Attributes&    attrs);
+    
+    void endElement(
+        const XMLCh* const   uri,
+        const XMLCh* const   localname,
+        const XMLCh* const   qname);
+
+    void characters(const XMLCh *const chars, const XMLSize_t length);
+    
+    void startDocument();
+
+    void endDocument();
+
+private:
+    ProppatchRequest *davrq;
+    pool_handle_t    *pool;
+
+    bool             davPropTag;
+    XmlElement       *rxprop; /* root of xml property */
+    XmlElement       *cxprop; /* current element */
+    DavProperty      *property;
+    int              updateMode; /* 0 = set, 1 = remove */
+};
+
 #endif	/* SAXHANDLER_H */
 
--- a/src/server/webdav/webdav.c	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/webdav/webdav.c	Wed May 16 12:47:28 2012 +0200
@@ -46,6 +46,8 @@
     
     if(!strcmp(method, "PROPFIND")) {
         return webdav_propfind(pb, sn, rq);
+    } else if(!strcmp(method, "PROPPATCH")) {
+        return webdav_proppatch(pb, sn, rq);
     } else if(!strcmp(method, "PUT")) {
         return webdav_put(pb, sn, rq);
     }
@@ -243,6 +245,48 @@
     return REQ_PROCEED;
 }
 
+int webdav_proppatch(pblock *pb, Session *sn, Request *rq) {
+    /* TODO: clean up if errors occurs */
+    /* TODO: this is the same code as in propfind */
+
+    /* Get request body which contains the webdav XML request */
+    char   *xml_body;
+    size_t xml_len = 0;
+
+    char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
+    if(ctlen) {
+        xml_len = atoi(ctlen);
+    } else {
+        /* invalid request */
+        printf("invalid request\n");
+        return REQ_ABORTED;
+    }
+
+    xml_body = pool_malloc(sn->pool, xml_len + 1);
+    if(xml_body == NULL) {
+        return REQ_ABORTED;
+    }
+    xml_body[xml_len] = 0;
+    if(!xml_body) {
+        /* server error */
+        printf("server error\n");
+        return REQ_ABORTED;
+    }
+
+    /* get request body */
+    int r = 0;
+    char *xb = xml_body;
+    size_t xl = xml_len;
+    while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
+        xb += r;
+        xl -= r;
+    }
+    
+    
+    
+    return REQ_PROCEED;
+}
+
 void dav_resource_response(PropfindRequest *davrq, sstr_t path, sstr_t uri) {
     printf("dav_resource_response %s %s\n", sstrdub(path).ptr, sstrdub(uri).ptr);
     
--- a/src/server/webdav/webdav.h	Sun May 06 10:09:27 2012 +0200
+++ b/src/server/webdav/webdav.h	Wed May 16 12:47:28 2012 +0200
@@ -49,7 +49,11 @@
 typedef struct DAVPropertyBackend   DAVPropertyBackend;
 
 typedef struct PropfindRequest      PropfindRequest;
+typedef struct ProppatchRequest     ProppatchRequest;
 typedef struct DavProperty          DavProperty;
+typedef struct DavPropertyCt        DavPropertyCt;
+
+typedef struct XmlElement           XmlElement;
 
 struct PropfindRequest {
     Session            *sn;
@@ -70,11 +74,37 @@
     sbuf_t             *out;
 };
 
+struct ProppatchRequest {
+    Session            *sn;
+    Request            *rq;
+    
+    UcxDlist           *setProps;    /* XmlElement list, set props */
+    UcxDlist           *removeProps; /* DavProperty list, remove props */
+    
+    
+};
+
 struct DavProperty {
     char *xmlns;
     char *name;
 };
 
+struct DavPropertyCt {
+    char           *xmlns;
+    char           *name;
+    DavPropertyCt  **props;
+    int            npr;
+};
+
+struct XmlElement {
+    char           *xmlns;
+    char           *name;
+    char           *content;
+    int            *ctlen;
+    int            *numelm;
+    XmlElement     **elms;
+};
+
 /*
  * dav_res_propfind_f
  * 
@@ -96,6 +126,7 @@
 int webdav_service(pblock *pb, Session *sn, Request *rq);
 int webdav_put(pblock *pb, Session *sn, Request *rq);
 int webdav_propfind(pblock *pb, Session *sn, Request *rq);
+int webdav_proppatch(pblock *pb, Session *sn, Request *rq);
 
 void dav_resource_response(PropfindRequest *rq, sstr_t path, sstr_t uri);
 

mercurial