From b9dfcf5ccf4e429a19b36dea126f012e5bee9ec4 Mon Sep 17 00:00:00 2001 From: "roberto@localhost.localdomain" Date: Thu, 19 Nov 2009 11:59:35 +0100 Subject: [PATCH] shared memory base implementation --- Makefile.BSD.Py25 | 9 +- Makefile.FreeBSD.Py25 | 9 +- Makefile.Linux.Py24 | 24 +++- Makefile.Linux.Py25 | 9 +- Makefile.Linux.Py26 | 9 +- Makefile.ROCK_SOLID.Py26 | 9 +- uwsgi.c | 66 ++++++++++- uwsgi.class | Bin 0 -> 5634 bytes uwsgi.h | 9 ++ uwsgi.java | 236 +++++++++++++++++++++++++++++++++++++++ uwsgi_pymodule.c | 214 +++++++++++++++++++++++++++++++++++ 11 files changed, 571 insertions(+), 23 deletions(-) create mode 100644 uwsgi.class create mode 100644 uwsgi.java create mode 100644 uwsgi_pymodule.c diff --git a/Makefile.BSD.Py25 b/Makefile.BSD.Py25 index 23bf5244..8eb2bc40 100644 --- a/Makefile.BSD.Py25 +++ b/Makefile.BSD.Py25 @@ -12,8 +12,8 @@ PROGRAM=uwsgi all: uwsgi -uwsgi: utils.o socket.o main.o - $(CC) $(LD_FLAGS) utils.o socket.o main.o -o $(PROGRAM) +uwsgi: utils.o socket.o pymodule.o main.o + $(CC) $(LD_FLAGS) utils.o socket.o pymodule.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c @@ -21,8 +21,11 @@ utils.o: utils.c socket.o: socket.c $(CC) -c $(CFLAGS) socket.c +pymodule.o: uwsgi_pymodule.c + $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c + main.o: uwsgi.c $(CC) -c $(CFLAGS) -o main.o uwsgi.c clean: - rm -f utils.o socket.o main.o + rm -f utils.o socket.o pymodule.o main.o diff --git a/Makefile.FreeBSD.Py25 b/Makefile.FreeBSD.Py25 index 4eeff1e2..f34d99bc 100644 --- a/Makefile.FreeBSD.Py25 +++ b/Makefile.FreeBSD.Py25 @@ -12,8 +12,8 @@ PROGRAM=uwsgi all: uwsgi -uwsgi: utils.o socket.o main.o - $(CC) $(LD_FLAGS) utils.o socket.o main.o -o $(PROGRAM) +uwsgi: utils.o socket.o pymodule.o main.o + $(CC) $(LD_FLAGS) utils.o socket.o pymodule.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c @@ -21,8 +21,11 @@ utils.o: utils.c socket.o: socket.c $(CC) -c $(CFLAGS) socket.c +pymodule.o: uwsgi_pymodule.c + $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c + main.o: uwsgi.c $(CC) -c $(CFLAGS) -o main.o uwsgi.c clean: - rm -f utils.o socket.o main.o + rm -f utils.o socket.o pymodule.o main.o diff --git a/Makefile.Linux.Py24 b/Makefile.Linux.Py24 index 76f368cf..fa7ed1e4 100644 --- a/Makefile.Linux.Py24 +++ b/Makefile.Linux.Py24 @@ -5,7 +5,27 @@ PYTHON_LIBS=`python2.4-config --libs` XML_CFLAGS=`xml2-config --cflags` XML_LIBS=`xml2-config --libs` +CFLAGS=$(PYTHON_CFLAGS) $(XML_CFLAGS) +LD_FLAGS=$(PYTHON_LIBS) $(XML_LIBS) + +PROGRAM=uwsgi24 + all: uwsgi -uwsgi: - $(CC) -o uwsgi24 $(PYTHON_CFLAGS) $(PYTHON_LIBS) $(XML_CFLAGS) $(XML_LIBS) utils.c socket.c uwsgi.c +uwsgi: utils.o socket.o pymodule.o main.o + $(CC) $(LD_FLAGS) utils.o socket.o pymodule.o main.o -o $(PROGRAM) + +utils.o: utils.c + $(CC) -c $(CFLAGS) utils.c + +socket.o: socket.c + $(CC) -c $(CFLAGS) socket.c + +pymodule.o: uwsgi_pymodule.c + $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c + +main.o: uwsgi.c + $(CC) -c $(CFLAGS) -o main.o uwsgi.c + +clean: + rm -f utils.o socket.o pymodule.o main.o diff --git a/Makefile.Linux.Py25 b/Makefile.Linux.Py25 index ceff1a07..969c656a 100644 --- a/Makefile.Linux.Py25 +++ b/Makefile.Linux.Py25 @@ -12,8 +12,8 @@ PROGRAM=uwsgi all: uwsgi -uwsgi: utils.o socket.o main.o - $(CC) $(LD_FLAGS) utils.o socket.o main.o -o $(PROGRAM) +uwsgi: utils.o socket.o pymodule.o main.o + $(CC) $(LD_FLAGS) utils.o socket.o pymodule.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c @@ -21,8 +21,11 @@ utils.o: utils.c socket.o: socket.c $(CC) -c $(CFLAGS) socket.c +pymodule.o: uwsgi_pymodule.c + $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c + main.o: uwsgi.c $(CC) -c $(CFLAGS) -o main.o uwsgi.c clean: - rm -f utils.o socket.o main.o + rm -f utils.o socket.o pymodule.o main.o diff --git a/Makefile.Linux.Py26 b/Makefile.Linux.Py26 index 09717ebf..36c8d44a 100644 --- a/Makefile.Linux.Py26 +++ b/Makefile.Linux.Py26 @@ -12,8 +12,8 @@ PROGRAM=uwsgi26 all: uwsgi -uwsgi: utils.o socket.o main.o - $(CC) $(LD_FLAGS) utils.o socket.o main.o -o $(PROGRAM) +uwsgi: utils.o socket.o pymodule.o main.o + $(CC) $(LD_FLAGS) utils.o socket.o pymodule.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c @@ -21,8 +21,11 @@ utils.o: utils.c socket.o: socket.c $(CC) -c $(CFLAGS) socket.c +pymodule.o: uwsgi_pymodule.c + $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c + main.o: uwsgi.c $(CC) -c $(CFLAGS) -o main.o uwsgi.c clean: - rm -f utils.o socket.o main.o + rm -f utils.o socket.o pymodule.o main.o diff --git a/Makefile.ROCK_SOLID.Py26 b/Makefile.ROCK_SOLID.Py26 index 0c0e03b0..604d46a1 100644 --- a/Makefile.ROCK_SOLID.Py26 +++ b/Makefile.ROCK_SOLID.Py26 @@ -10,8 +10,8 @@ PROGRAM=uwsgi26_rs all: uwsgi -uwsgi: utils.o socket.o main.o - $(CC) $(LD_FLAGS) utils.o socket.o main.o -o $(PROGRAM) +uwsgi: utils.o socket.o pymodule.o main.o + $(CC) $(LD_FLAGS) utils.o socket.o pymodule.o main.o -o $(PROGRAM) utils.o: utils.c $(CC) -c $(CFLAGS) utils.c @@ -19,8 +19,11 @@ utils.o: utils.c socket.o: socket.c $(CC) -c $(CFLAGS) socket.c +pymodule.o: uwsgi_pymodule.c + $(CC) -c $(CFLAGS) -o pymodule.o uwsgi_pymodule.c + main.o: uwsgi.c $(CC) -c $(CFLAGS) -o main.o uwsgi.c clean: - rm -f utils.o socket.o main.o + rm -f utils.o socket.o pymodule.o main.o diff --git a/uwsgi.c b/uwsgi.c index cb960eba..db6cdc34 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -143,7 +143,8 @@ struct wsgi_request wsgi_req; struct timeval start_of_uwsgi ; -char *sharedarea ; +extern PyMethodDef *uwsgi_methods ; +extern PyMethodDef *null_methods ; #ifndef UNBIT #ifndef ROCK_SOLID @@ -578,12 +579,14 @@ int main(int argc, char *argv[], char *envp[]) { int socket_type; socklen_t socket_type_len; + sharedareasize = 0 ; + gettimeofday(&start_of_uwsgi, NULL) ; setlinebuf(stdout); cwd = uwsgi_get_cwd(); - binary_path = malloc(strlen(argv[0])) ; + binary_path = malloc(strlen(argv[0])+1) ; if (binary_path == NULL) { perror("malloc()"); exit(1); @@ -603,12 +606,12 @@ int main(int argc, char *argv[], char *envp[]) { #ifndef UNBIT #ifndef ROCK_SOLID - while ((i = getopt (argc, argv, "s:p:t:x:d:l:O:v:b:mcaCTPiMhrR:z:w:j:H:")) != -1) { + while ((i = getopt (argc, argv, "s:p:t:x:d:l:O:v:b:mcaCTPiMhrR:z:w:j:H:A:")) != -1) { #else - while ((i = getopt (argc, argv, "s:p:t:d:l:v:b:aCMhrR:z:j:H:")) != -1) { + while ((i = getopt (argc, argv, "s:p:t:d:l:v:b:aCMhrR:z:j:H:A:")) != -1) { #endif #else - while ((i = getopt (argc, argv, "p:t:mTPiv:b:rMR:Sz:w:C:j:H:")) != -1) { + while ((i = getopt (argc, argv, "p:t:mTPiv:b:rMR:Sz:w:C:j:H:A:")) != -1) { #endif switch(i) { case 'j': @@ -617,6 +620,9 @@ int main(int argc, char *argv[], char *envp[]) { case 'H': pyhome = optarg; break; + case 'A': + sharedareasize = atoi(optarg); + break; #ifdef UNBIT case 'S': single_interpreter = 1; @@ -779,16 +785,60 @@ int main(int argc, char *argv[], char *envp[]) { #else Py_SetProgramName("uWSGI"); #endif - Py_Initialize() ; + Py_Initialize() ; wsgi_spitout = PyCFunction_New(uwsgi_spit_method,NULL) ; wsgi_writeout = PyCFunction_New(uwsgi_write_method,NULL) ; + if (sharedareasize > 0) { + sharedareamutex = mmap(NULL, sizeof(pthread_mutexattr_t) + sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANONYMOUS , -1, 0); + if (!sharedareamutex) { + perror("mmap()"); + exit(1); + } + sharedarea = mmap(NULL, getpagesize() * sharedareasize, PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANONYMOUS , -1, 0); + if (sharedarea) { + fprintf(stderr,"shared area mapped at %p, you can access it with uwsgi.sharedarea_read(ptr,[len])\n", sharedarea); + if (pthread_mutexattr_init((pthread_mutexattr_t *)sharedareamutex)) { + fprintf(stderr,"unable to allocate mutexattr structure\n"); + exit(1); + } + if (pthread_mutexattr_setpshared((pthread_mutexattr_t *)sharedareamutex, PTHREAD_PROCESS_SHARED)) { + fprintf(stderr,"unable to share mutex\n"); + exit(1); + } + if (pthread_mutex_init((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t), (pthread_mutexattr_t *)sharedareamutex)) { + fprintf(stderr,"unable to initialize mutex\n"); + exit(1); + } + + } + else { + perror("mmap()"); + exit(1); + } + + uwsgi_module = Py_InitModule("uwsgi", uwsgi_methods); + if (uwsgi_module == NULL) { + fprintf(stderr,"could not initialize the uwsgi python module\n"); + exit(1); + } + } + else { + uwsgi_module = Py_InitModule("uwsgi", null_methods); + if (uwsgi_module == NULL) { + fprintf(stderr,"could not initialize the uwsgi python module\n"); + exit(1); + } + } + + #ifdef ROCK_SOLID + wi = malloc(sizeof(struct uwsgi_app)); if (wi == NULL) { perror("malloc()"); @@ -874,6 +924,8 @@ int main(int argc, char *argv[], char *envp[]) { } #endif + + #ifndef ROCK_SOLID if (single_interpreter == 1) { init_uwsgi_vars(); @@ -936,6 +988,8 @@ int main(int argc, char *argv[], char *envp[]) { fprintf(stderr,"request/response buffer (%d bytes) allocated.\n", buffer_size); + + /* preforking() */ if (master_process == 0) { fprintf(stderr, "spawned uWSGI worker 0 (pid: %d)\n", mypid); diff --git a/uwsgi.class b/uwsgi.class new file mode 100644 index 0000000000000000000000000000000000000000..be15f4d6e62c49ba522fcb2e95aa6e58214cba43 GIT binary patch literal 5634 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 literal 0 HcmV?d00001 diff --git a/uwsgi.h b/uwsgi.h index 9a209364..15d9a3ee 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -9,6 +9,8 @@ #include #include #include +#include + #include #include @@ -16,6 +18,7 @@ #include #include +#include #ifdef UNBIT #undef _XOPEN_SOURCE @@ -154,3 +157,9 @@ void uwsgi_xml_config(void); #ifndef ROCK_SOLID void uwsgi_wsgi_config(void); #endif + + +char *sharedarea ; +void *sharedareamutex ; +int sharedareasize ; +PyObject *uwsgi_module; diff --git a/uwsgi.java b/uwsgi.java new file mode 100644 index 00000000..abf1973b --- /dev/null +++ b/uwsgi.java @@ -0,0 +1,236 @@ +import java.io.*; +import java.net.*; +import javax.servlet.*; +import javax.servlet.http.*; +import java.util.Enumeration; +import org.apache.catalina.util.IOTools; + +public class uwsgi extends HttpServlet { + + private String mountpoint = null; + + public void init(ServletConfig config) throws ServletException { + super.init(config); + + String servletName = getServletConfig().getServletName(); + if (servletName == null) + servletName = ""; + if (servletName.startsWith("org.apache.catalina.INVOKER.")) + throw new UnavailableException + ("Cannot invoke uWSGIServlet through the invoker"); + + if (getServletConfig().getInitParameter("mountpoint") != null) { + mountpoint = getServletConfig().getInitParameter("mountpoint"); + if (mountpoint.length() <= 1) { + mountpoint = null ; + } + } + } + + + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + uWSGIHandler(request, response); + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + uWSGIHandler(request, response); + } + + + private void uWSGIHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException { + + Socket client = new Socket("localhost",3017); + ByteArrayOutputStream uwsgi_request = new ByteArrayOutputStream() ; + DataOutputStream wos = new DataOutputStream(uwsgi_request); + + DataOutputStream os = new DataOutputStream(client.getOutputStream()); + DataInputStream is = new DataInputStream( client.getInputStream() ); + + + ServletOutputStream out = response.getOutputStream(); + + boolean hasBody = false; + + wos.writeShort(swapShort( (short) 14)); + wos.writeBytes("REQUEST_METHOD"); + wos.writeShort(swapShort( (short) request.getMethod().length() ) ); + wos.writeBytes( request.getMethod() ); + + wos.writeShort(swapShort( (short) 12)); + wos.writeBytes("QUERY_STRING"); + if (request.getQueryString() != null) { + wos.writeShort(swapShort( (short) request.getQueryString().length() ) ); + wos.writeBytes( request.getQueryString() ); + } + else { + wos.writeShort(0); + } + + wos.writeShort(swapShort( (short) 11)); + wos.writeBytes("SERVER_NAME"); + wos.writeShort(swapShort( (short) request.getServerName().length() ) ); + wos.writeBytes( request.getServerName() ); + + wos.writeShort(swapShort( (short) 11)); + wos.writeBytes("SERVER_PORT"); + wos.writeShort(swapShort( (short) Integer.toString(request.getServerPort()).length() ) ); + wos.writeBytes( Integer.toString(request.getServerPort()) ); + + wos.writeShort(swapShort( (short) 15)); + wos.writeBytes("SERVER_PROTOCOL"); + wos.writeShort(swapShort( (short) request.getProtocol().length() ) ); + wos.writeBytes( request.getProtocol() ); + + wos.writeShort(swapShort( (short) 11)); + wos.writeBytes("REQUEST_URI"); + if (request.getQueryString() != null) { + if (request.getQueryString().length() > 0) { + wos.writeShort(swapShort( (short) (request.getRequestURI().length()+1+request.getQueryString().length()) ) ); + wos.writeBytes( request.getRequestURI()+"?"+request.getQueryString() ); + } + else { + wos.writeShort(swapShort( (short) request.getRequestURI().length() ) ); + wos.writeBytes( request.getRequestURI() ); + } + } + else { + wos.writeShort(swapShort( (short) request.getRequestURI().length() ) ); + wos.writeBytes( request.getRequestURI() ); + } + + + if (mountpoint != null) { + wos.writeShort(swapShort( (short) 11)); + wos.writeBytes("SCRIPT_NAME"); + wos.writeShort(swapShort( (short) mountpoint.length() ) ) ; + wos.writeBytes( mountpoint ) ; + } + + + wos.writeShort(swapShort( (short) 9)); + wos.writeBytes("PATH_INFO"); + if (mountpoint != null) { + wos.writeShort(swapShort( (short) (request.getRequestURI().length() - mountpoint.length()) ) ); + wos.writeBytes( request.getRequestURI().substring(mountpoint.length()) ); + } + else { + wos.writeShort(swapShort( (short) request.getRequestURI().length() ) ); + wos.writeBytes( request.getRequestURI() ); + } + + wos.writeShort(swapShort( (short) 11)); + wos.writeBytes("REMOTE_ADDR"); + wos.writeShort(swapShort( (short) request.getRemoteAddr().length() ) ); + wos.writeBytes( request.getRemoteAddr() ); + + if (request.getRemoteUser() != null) { + wos.writeShort(swapShort( (short) 11)); + wos.writeBytes("REMOTE_USER"); + wos.writeShort(swapShort( (short) request.getRemoteUser().length() ) ); + wos.writeBytes( request.getRemoteUser() ); + } + + if (request.getContentType() != null) { + wos.writeShort(swapShort( (short) 12)); + wos.writeBytes("CONTENT_TYPE"); + wos.writeShort(swapShort( (short) request.getContentType().length() ) ); + wos.writeBytes( request.getContentType() ); + } + + if (request.getContentLength() > 0) { + wos.writeShort(swapShort( (short) 14)); + wos.writeBytes("CONTENT_LENGTH"); + String sContentLength = new Integer(request.getContentLength()).toString(); + wos.writeShort(swapShort( (short) sContentLength.length() ) ); + wos.writeBytes( sContentLength ); + hasBody = true; + } + + + // taken from CGI servlet + + Enumeration headers = request.getHeaderNames(); + String header = null; + while (headers.hasMoreElements()) { + header = null; + header = ((String) headers.nextElement()).toUpperCase(); + wos.writeShort(swapShort( (short) ("HTTP_" + header.replace('-', '_')).length() )); + wos.writeBytes("HTTP_" + header.replace('-', '_')); + wos.writeShort(swapShort( (short) request.getHeader(header).length() )); + wos.writeBytes( request.getHeader(header) ); + } + + + os.writeByte(0); + os.writeShort( swapShort( (short) wos.size() ) ); + os.writeByte(0); + + uwsgi_request.writeTo( os ); + + + if (hasBody) { + IOTools.flow(request.getInputStream(), os); + } + + boolean statusParsed = false ; + for(;;) { + String line = byte_readline(is) ; + if (line == "") { + break; + } + if (statusParsed == false) { + String[] status = line.split(" ",3); + response.setStatus( Integer.parseInt(status[1]) ); + statusParsed = true ; + } + else { + String[] keyval = line.split(": ",2); + if (keyval.length == 2) { + response.addHeader(keyval[0], keyval[1]); + } + else { + break; + } + } + } + + byte cb[] = new byte[4096]; + int len = 0; + for(;;) { + len = is.read(cb,0,4096) ; + if ( len > 0) { + out.write(cb,0,len); + } + else { + break; + } + } + + + } + + private String byte_readline(DataInputStream is) throws IOException { + + ByteArrayOutputStream line = new ByteArrayOutputStream(); + for(;;) { + byte b = is.readByte(); + if (b == 10) { + break ; + } + line.write(b) ; + } + + return line.toString("ASCII").replaceAll("\\n","").replaceAll("\\r",""); + } + + private short swapShort(short x) { + + short tmp1 = (short) (x>>8) ; + short tmp2 = (short) (x<<8) ; + return (short) (tmp1 | tmp2) ; + } + +} diff --git a/uwsgi_pymodule.c b/uwsgi_pymodule.c new file mode 100644 index 00000000..8e0fa13b --- /dev/null +++ b/uwsgi_pymodule.c @@ -0,0 +1,214 @@ +#include "uwsgi.h" + +PyObject *py_uwsgi_sharedarea_inclong(PyObject *self, PyObject *args) { + PyObject *arg0 ; + int pos = 0 ; + long value ; + + if (sharedareasize <= 0) { + Py_INCREF(Py_None); + return Py_None; + } + + arg0 = PyTuple_GetItem(args, 0); + if (!PyInt_Check(arg0)) { + Py_INCREF(Py_None); + return Py_None; + } + + pos = PyInt_AsLong(arg0); + + if (pos+4 >= getpagesize()*sharedareasize) { + Py_INCREF(Py_None); + return Py_None; + } + + pthread_mutex_lock((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t)); + memcpy(&value, sharedarea+pos, 4); + value++; + memcpy(sharedarea+pos, &value,4); + pthread_mutex_unlock((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t)); + + return PyInt_FromLong(value); + +} + +PyObject *py_uwsgi_sharedarea_writelong(PyObject *self, PyObject *args) { + PyObject *arg0,*arg1 ; + int pos = 0 ; + long value ; + + if (sharedareasize <= 0) { + Py_INCREF(Py_None); + return Py_None; + } + + arg0 = PyTuple_GetItem(args, 0); + if (!PyInt_Check(arg0)) { + Py_INCREF(Py_None); + return Py_None; + } + + pos = PyInt_AsLong(arg0); + + if (pos+4 >= getpagesize()*sharedareasize) { + Py_INCREF(Py_None); + return Py_None; + } + + arg1 = PyTuple_GetItem(args, 1); + if (!PyInt_Check(arg1)) { + Py_INCREF(Py_None); + return Py_None; + } + + pthread_mutex_lock((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t)); + value = (long) PyInt_AsLong(arg1); + memcpy(sharedarea+pos, &value,4); + pthread_mutex_unlock((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t)); + + return PyInt_FromLong(value); + +} + +PyObject *py_uwsgi_sharedarea_writebyte(PyObject *self, PyObject *args) { + PyObject *arg0,*arg1 ; + int pos = 0 ; + char value ; + + if (sharedareasize <= 0) { + Py_INCREF(Py_None); + return Py_None; + } + + arg0 = PyTuple_GetItem(args, 0); + if (!PyInt_Check(arg0)) { + Py_INCREF(Py_None); + return Py_None; + } + + pos = PyInt_AsLong(arg0); + + if (pos >= getpagesize()*sharedareasize) { + Py_INCREF(Py_None); + return Py_None; + } + + arg1 = PyTuple_GetItem(args, 1); + if (!PyInt_Check(arg1)) { + Py_INCREF(Py_None); + return Py_None; + } + + value = (char) PyInt_AsLong(arg1); + sharedarea[pos] = value; + + return PyInt_FromLong(sharedarea[pos]); + +} + +PyObject *py_uwsgi_sharedarea_readlong(PyObject *self, PyObject *args) { + PyObject *arg0 ; + int pos = 0 ; + long value ; + + if (sharedareasize <= 0) { + Py_INCREF(Py_None); + return Py_None; + } + + arg0 = PyTuple_GetItem(args, 0); + if (!PyInt_Check(arg0)) { + Py_INCREF(Py_None); + return Py_None; + } + + pos = PyInt_AsLong(arg0); + + if (pos+4 >= getpagesize()*sharedareasize) { + Py_INCREF(Py_None); + return Py_None; + } + + pthread_mutex_lock((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t)); + memcpy(&value, sharedarea+pos, 4); + pthread_mutex_unlock((pthread_mutex_t *) sharedareamutex + sizeof(pthread_mutexattr_t)); + + return PyInt_FromLong(value); + +} + + +PyObject *py_uwsgi_sharedarea_readbyte(PyObject *self, PyObject *args) { + PyObject *arg0 ; + int pos = 0 ; + + if (sharedareasize <= 0) { + Py_INCREF(Py_None); + return Py_None; + } + + arg0 = PyTuple_GetItem(args, 0); + if (!PyInt_Check(arg0)) { + Py_INCREF(Py_None); + return Py_None; + } + + pos = PyInt_AsLong(arg0); + + if (pos >= getpagesize()*sharedareasize) { + Py_INCREF(Py_None); + return Py_None; + } + + return PyInt_FromLong(sharedarea[pos]); + +} + +PyObject *py_uwsgi_sharedarea_read(PyObject *self, PyObject *args) { + PyObject *arg0, *arg1; + + int len = 1 ; + int pos = 0 ; + + if (sharedareasize <= 0) { + Py_INCREF(Py_None); + return Py_None; + } + + arg0 = PyTuple_GetItem(args, 0); + if (!PyInt_Check(arg0)) { + Py_INCREF(Py_None); + return Py_None; + } + arg1 = PyTuple_GetItem(args, 1); + if (PyInt_Check(arg1)) { + len = PyInt_AsLong(arg1); + } + + pos = PyInt_AsLong(arg0); + + if (pos+len >= getpagesize()*sharedareasize) { + Py_INCREF(Py_None); + return Py_None; + } + + return PyString_FromStringAndSize(sharedarea+pos, len); +} + + + +PyMethodDef uwsgi_methods[] = { + {"sharedarea_read", py_uwsgi_sharedarea_read, METH_VARARGS, ""}, + {"sharedarea_readbyte", py_uwsgi_sharedarea_readbyte, METH_VARARGS, ""}, + {"sharedarea_writebyte", py_uwsgi_sharedarea_writebyte, METH_VARARGS, ""}, + {"sharedarea_readlong", py_uwsgi_sharedarea_readlong, METH_VARARGS, ""}, + {"sharedarea_writelong", py_uwsgi_sharedarea_writelong, METH_VARARGS, ""}, + {"sharedarea_inclong", py_uwsgi_sharedarea_inclong, METH_VARARGS, ""}, + {NULL, NULL}, +}; + +PyMethodDef null_methods[] = { + {NULL, NULL}, +}; +