# HG changeset patch # User Olaf Wintermann # Date 1337165248 -7200 # Node ID e8619defde14b2e15237e2d4ff18e640c1971ad7 # Parent f387669912e8316e6a9b01e9f5d80de3c4525fcf added event handler diff -r f387669912e8 -r e8619defde14 src/server/Makefile --- 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 = diff -r f387669912e8 -r e8619defde14 src/server/daemon/config.c --- 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;iobjects->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"))) { diff -r f387669912e8 -r e8619defde14 src/server/daemon/event.h --- /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 */ + diff -r f387669912e8 -r e8619defde14 src/server/daemon/event_solaris.c --- /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 +#include +#include + +#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;iports[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;iportev_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); +} diff -r f387669912e8 -r e8619defde14 src/server/daemon/event_solaris.h --- /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 +#include + +#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 */ + diff -r f387669912e8 -r e8619defde14 src/server/daemon/httplistener.c --- 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"); diff -r f387669912e8 -r e8619defde14 src/server/daemon/objs.mk --- 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) diff -r f387669912e8 -r e8619defde14 src/server/public/nsapi.h --- 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 #include #include /* new */ +#include #ifndef HPUX #include #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 diff -r f387669912e8 -r e8619defde14 src/server/util/ereport.h --- 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 */ diff -r f387669912e8 -r e8619defde14 src/server/util/pool.c --- 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; } diff -r f387669912e8 -r e8619defde14 src/server/util/system.c --- 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 #endif #include "../daemon/netsite.h" -#include "ereport.h" +//include "ereport.h" #ifdef XP_WIN32 #include diff -r f387669912e8 -r e8619defde14 src/server/util/systhr.c --- 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 #endif -#ifdef THREAD_WIN32 -#include - -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 @@ // } +/* + * TODO: reimplement with pthread api + */ NSAPI_PUBLIC int systhread_newkey() { diff -r f387669912e8 -r e8619defde14 src/server/util/systhr.h --- 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); diff -r f387669912e8 -r e8619defde14 src/server/webdav/davparser.cpp --- 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; +} diff -r f387669912e8 -r e8619defde14 src/server/webdav/davparser.h --- 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 diff -r f387669912e8 -r e8619defde14 src/server/webdav/saxhandler.cpp --- 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() { + +} + diff -r f387669912e8 -r e8619defde14 src/server/webdav/saxhandler.h --- 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 */ diff -r f387669912e8 -r e8619defde14 src/server/webdav/webdav.c --- 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); diff -r f387669912e8 -r e8619defde14 src/server/webdav/webdav.h --- 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);