Skip to content
Snippets Groups Projects
Commit f9e60dbbf97a authored by Jean-Francois Pieronne's avatar Jean-Francois Pieronne
Browse files

v1.1.2 update

parent ed93d31e39c3
No related branches found
No related tags found
No related merge requests found
...@@ -170,6 +170,13 @@ ...@@ -170,6 +170,13 @@
import wasd import wasd
wasd.wsgi_run(obvious_example) wasd.wsgi_run(obvious_example)
PEP 333 specifies that WSGI should not buffer output and pyRTE complies but
some tools (like Mercurial) don't buffer themselves and end up sending many
very small records. If buffered the throughput boost for Mercurial is about
x4. This forced buffering may be enabled on a per-application basis using the
mapping rule 'script=param=PYRTE=/WSGI=BUFFER' or by defining the logical name
PYRTE_WSGI_FORCE_BUFFERING (in a wrapper procedure).
REFERENCES REFERENCES
---------- ----------
...@@ -238,6 +245,7 @@ ...@@ -238,6 +245,7 @@
script=param=PYRTE=/REUSE reuse this Python interpreter script=param=PYRTE=/REUSE reuse this Python interpreter
script=param=PYRTE=/NOREUSE do not reuse this Python interpreter script=param=PYRTE=/NOREUSE do not reuse this Python interpreter
script=param=PYRTE=/NOSTREAM do not issue the stream-mode header script=param=PYRTE=/NOSTREAM do not issue the stream-mode header
script=param=PYRTE=/WSGI=BUFFER force WSGI buffering mode
LOGICAL NAMES LOGICAL NAMES
...@@ -251,7 +259,8 @@ ...@@ -251,7 +259,8 @@
PYRTE_CACHE_MAX integer size of code cache (zero to compare uncached) PYRTE_CACHE_MAX integer size of code cache (zero to compare uncached)
PYRTE_NOREUSE_INTERPRETER do not reuse interpreter for each script instance PYRTE_NOREUSE_INTERPRETER do not reuse interpreter for each script instance
PYRTE_USAGE_LIMIT integer number of requests before voluntary exit PYRTE_USAGE_LIMIT integer number of requests before voluntary exit
PYRTE_WSGI_FORCE_BUFFERING enable buffering with WASD, this break the WSGI
specification but may give a performance boost.
BUILD DETAILS BUILD DETAILS
------------- -------------
...@@ -262,9 +271,12 @@ ...@@ -262,9 +271,12 @@
VERSION HISTORY (update SOFTWAREVN as well!) VERSION HISTORY (update SOFTWAREVN as well!)
--------------- ---------------
19-APR-2008 JFP v1.1.2, WSGI buffered output (see description above)
17-JAN-2008 MGD v1.1.1, CgiVar() and CgiVarDclSymbol() ensure an empty
SCRIPT_NAME *is* empty (not the WASD-ism "/")
05-JAN-2008 MGD v1.1.0, WSGI support 05-JAN-2008 MGD v1.1.0, WSGI support
22-APR-2007 MGD v1.0.0, initial development 22-APR-2007 MGD v1.0.0, initial development
*/ */
/*****************************************************************************/ /*****************************************************************************/
#define SOFTWARECR "Copyright (C) 2007,2008 Mark G.Daniel" #define SOFTWARECR "Copyright (C) 2007,2008 Mark G.Daniel"
...@@ -265,10 +277,10 @@ ...@@ -265,10 +277,10 @@
05-JAN-2008 MGD v1.1.0, WSGI support 05-JAN-2008 MGD v1.1.0, WSGI support
22-APR-2007 MGD v1.0.0, initial development 22-APR-2007 MGD v1.0.0, initial development
*/ */
/*****************************************************************************/ /*****************************************************************************/
#define SOFTWARECR "Copyright (C) 2007,2008 Mark G.Daniel" #define SOFTWARECR "Copyright (C) 2007,2008 Mark G.Daniel"
#define SOFTWAREVN "1.1.0" #define SOFTWAREVN "1.1.2"
#define SOFTWARENM "PYRTE" #define SOFTWARENM "PYRTE"
#ifdef __ALPHA #ifdef __ALPHA
# define SOFTWAREID SOFTWARENM " AXP-" SOFTWAREVN # define SOFTWAREID SOFTWARENM " AXP-" SOFTWAREVN
...@@ -357,7 +369,8 @@ ...@@ -357,7 +369,8 @@
UsageLimit, UsageLimit,
WasdHeadersSent, WasdHeadersSent,
WsgiHeadersSent, WsgiHeadersSent,
WsgiRunApp; WsgiRunApp,
WsgiForceBuffering;
unsigned long ExitStatus; unsigned long ExitStatus;
...@@ -570,6 +583,7 @@ ...@@ -570,6 +583,7 @@
int ByteCodeUpToDate (struct CodeCacheStruct*); int ByteCodeUpToDate (struct CodeCacheStruct*);
char* CgiVar (char*); char* CgiVar (char*);
char* CgiVarDclSymbol (char*); char* CgiVarDclSymbol (char*);
int EmptyScriptName (char*, char*);
void EnsureExit (unsigned long*); void EnsureExit (unsigned long*);
int lib$stop (__unknown_params); int lib$stop (__unknown_params);
void LoadByteCode (char*, char*, struct CodeCacheStruct*); void LoadByteCode (char*, char*, struct CodeCacheStruct*);
...@@ -623,6 +637,9 @@ ...@@ -623,6 +637,9 @@
fflush (stdout); fflush (stdout);
} }
WsgiForceBuffering =
(TrnLnm ("PYRTE_WSGI_FORCE_BUFFERING", NULL) != NULL);
/* if it doesn't look like CGI environment then forget it */ /* if it doesn't look like CGI environment then forget it */
if (!TrnLnm ("HTTP$INPUT", NULL)) exit (SS$_ABORT); if (!TrnLnm ("HTTP$INPUT", NULL)) exit (SS$_ABORT);
...@@ -1511,7 +1528,7 @@ ...@@ -1511,7 +1528,7 @@
fwrite (DataPtr, DataLength, 1, stdout); fwrite (DataPtr, DataLength, 1, stdout);
/* WSGI always writes data unbuffered */ /* WSGI always writes data unbuffered */
if (WsgiRunApp) fflush (stdout); if (WsgiRunApp && !WsgiForceBuffering) fflush (stdout);
Py_INCREF (Py_None); Py_INCREF (Py_None);
return (Py_None); return (Py_None);
...@@ -2187,7 +2204,7 @@ ...@@ -2187,7 +2204,7 @@
/** if (Debug) fprintf (stdout, "pIter()\n"); **/ /** if (Debug) fprintf (stdout, "pIter()\n"); **/
AppOutputCount += DataLength; AppOutputCount += DataLength;
fwrite (DataPtr, DataLength, 1, stdout); fwrite (DataPtr, DataLength, 1, stdout);
fflush (stdout); if (!WsgiForceBuffering) fflush (stdout);
} }
Py_DECREF (pItem); Py_DECREF (pItem);
} }
...@@ -2463,6 +2480,9 @@ ...@@ -2463,6 +2480,9 @@
{ {
while (*cptr && *cptr != '/') cptr++; while (*cptr && *cptr != '/') cptr++;
if (!*cptr) break; if (!*cptr) break;
if (!strncmp (cptr, "/reuse", 6) || !strncmp (cptr, "/REUSE", 6)) if (!strncasecmp (cptr, "/wsgi=buffer", 12))
WsgiForceBuffering = 1;
else
if (!strncasecmp (cptr, "/reuse", 6))
ReuseInterpreter = 1; ReuseInterpreter = 1;
else else
...@@ -2467,5 +2487,5 @@ ...@@ -2467,5 +2487,5 @@
ReuseInterpreter = 1; ReuseInterpreter = 1;
else else
if (!strncmp (cptr, "/noreuse", 8) || !strncmp (cptr, "/NOREUSE", 8)) if (!strncasecmp (cptr, "/noreuse", 8))
ReuseInterpreter = 0; ReuseInterpreter = 0;
else else
...@@ -2470,5 +2490,5 @@ ...@@ -2470,5 +2490,5 @@
ReuseInterpreter = 0; ReuseInterpreter = 0;
else else
if (!strncmp (cptr, "/nostream", 9) || !strncmp (cptr, "/NOSTREAM", 9)) if (!strncasecmp (cptr, "/nostream", 9))
NoStreamMode = 1; NoStreamMode = 1;
else else
...@@ -2473,6 +2493,6 @@ ...@@ -2473,6 +2493,6 @@
NoStreamMode = 1; NoStreamMode = 1;
else else
if (!strncmp (cptr, "/dbug", 5) || !strncmp (cptr, "/DBUG", 5)) if (!strncasecmp (cptr, "/dbug", 5))
Debug = 1; Debug = 1;
cptr++; cptr++;
} }
...@@ -2630,7 +2650,8 @@ ...@@ -2630,7 +2650,8 @@
static int CalloutDone, static int CalloutDone,
StructLength; StructLength;
static char *NextVarNamePtr; static char *EmptyScriptNamePtr = NULL,
*NextVarNamePtr;
static char StructBuffer [CGIVAR_STRUCT_SIZE]; static char StructBuffer [CGIVAR_STRUCT_SIZE];
static FILE *CgiPlusIn; static FILE *CgiPlusIn;
...@@ -2672,7 +2693,15 @@ ...@@ -2672,7 +2693,15 @@
sptr = (NextVarNamePtr += SOUS); sptr = (NextVarNamePtr += SOUS);
NextVarNamePtr += Length; NextVarNamePtr += Length;
/* by default CGI variable names are prefixed by "WWW_", ignore */ /* by default CGI variable names are prefixed by "WWW_", ignore */
return (sptr + 4); sptr += 4;
/* ensure an empty SCRIPT_NAME *is* empty */
if (toupper(*sptr) != 'S') return (sptr);
if (toupper(*(sptr+1)) != 'C') return (sptr);
if (!EmptyScriptName (sptr, NULL)) return (sptr);
if (EmptyScriptNamePtr) return (EmptyScriptNamePtr);
EmptyScriptNamePtr = calloc (1, 13);
if (EmptyScriptNamePtr) strcpy (EmptyScriptNamePtr, "SCRIPT_NAME=");
return (EmptyScriptNamePtr);
} }
/* standard CGI */ /* standard CGI */
...@@ -2692,7 +2721,16 @@ ...@@ -2692,7 +2721,16 @@
for (cptr = VarName; *cptr && *sptr && *sptr != '='; cptr++, sptr++) for (cptr = VarName; *cptr && *sptr && *sptr != '='; cptr++, sptr++)
if (toupper(*cptr) != toupper(*sptr)) break; if (toupper(*cptr) != toupper(*sptr)) break;
/* if found return a pointer to the value */ /* if found return a pointer to the value */
if (!*cptr && *sptr == '=') return (sptr + 1); if (!*cptr && *sptr == '=')
{
sptr++;
/* ensure an empty SCRIPT_NAME *is* empty */
if (toupper(*sptr) != 'S') return (sptr);
if (toupper(*(sptr+1)) != 'C') return (sptr);
if (!EmptyScriptName (VarName, sptr)) return (sptr);
while (*sptr) sptr++;
return (sptr);
}
} }
/* not found */ /* not found */
return (NULL); return (NULL);
...@@ -2888,8 +2926,8 @@ ...@@ -2888,8 +2926,8 @@
strncpy (WwwName+4, cptr, sizeof(WwwName)-5); strncpy (WwwName+4, cptr, sizeof(WwwName)-5);
NameDsc.dsc$w_length = strlen(WwwName); NameDsc.dsc$w_length = strlen(WwwName);
ValueDsc.dsc$a_pointer = Value; ValueDsc.dsc$a_pointer = Value;
ValueDsc.dsc$w_length = 1023; ValueDsc.dsc$w_length = sizeof(Value)-1;
status = lib$get_symbol (&NameDsc, &ValueDsc, &ShortLength, NULL); status = lib$get_symbol (&NameDsc, &ValueDsc, &ShortLength, NULL);
if (status & 1) if (status & 1)
{ {
...@@ -2892,8 +2930,11 @@ ...@@ -2892,8 +2930,11 @@
status = lib$get_symbol (&NameDsc, &ValueDsc, &ShortLength, NULL); status = lib$get_symbol (&NameDsc, &ValueDsc, &ShortLength, NULL);
if (status & 1) if (status & 1)
{ {
cptr = malloc (ShortLength+1); /* ensure an empty SCRIPT_NAME *is* empty */
if (toupper(VarName[0]) != 'S' && EmptyScriptName (VarName, Value))
ShortLength = 0;
cptr = calloc (1, ShortLength+1);
memcpy (cptr, Value, ShortLength); memcpy (cptr, Value, ShortLength);
cptr[ShortLength] = '\0'; cptr[ShortLength] = '\0';
return (cptr); return (cptr);
...@@ -2910,6 +2951,44 @@ ...@@ -2910,6 +2951,44 @@
/*****************************************************************************/ /*****************************************************************************/
/* /*
Suppress the WASD-ism of an empty or 'root' script name (i.e. "/").
If 'VarValue' is none then 'VarName' is "NAME=<value>" string.
*/
int EmptyScriptName
(
char *VarName,
char *VarValue
)
{
char *cptr = "SCRIPT_NAME",
*sptr = VarName;
/*********/
/* begin */
/*********/
if (Debug) fprintf (stdout, "EmptyScriptName() %s %s\n", VarName, VarValue);
while (*cptr && *sptr && *sptr != '=')
{
if (*cptr != toupper(*sptr)) break;
cptr++;
sptr++;
}
if (*cptr || (*sptr && *sptr != '=')) return (0);
if (VarValue)
{
if (*(unsigned short*)VarValue != '/\0') return (0);
if (!*VarValue) return (0);
return (1);
}
if (*(unsigned short*)(sptr+1) != '/\0') return (0);
return (1);
}
/*****************************************************************************/
/*
If false then initialize the LIB$ stats timer. If false then initialize the LIB$ stats timer.
If true return a pointer to a static buffer containings a stats string. If true return a pointer to a static buffer containings a stats string.
*/ */
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment