summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual.tex9
-rw-r--r--include/request.h2
-rw-r--r--src/c/fastcgi.c4
-rw-r--r--src/c/http.c4
-rw-r--r--src/c/request.c32
-rw-r--r--tests/overflow.ur8
-rw-r--r--tests/overflow.urp4
-rw-r--r--tests/overflow.urs1
8 files changed, 58 insertions, 6 deletions
diff --git a/doc/manual.tex b/doc/manual.tex
index 8573c1c1..6691876d 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -321,6 +321,15 @@ These input files follow normal Ur syntax, with a few exceptions:
A word of warning: as for demo generation, tutorial generation calls Emacs to syntax-highlight Ur code.
+\subsection{Run-Time Options}
+
+Compiled applications consult a few environment variables to modify their behavior:
+
+\begin{itemize}
+ \item \cd{URWEB\_NUM\_THREADS}: alternative to the \cd{-t} command-line argument (currently used only by FastCGI)
+ \item \cd{URWEB\_STACK\_SIZE}: size of per-thread stacks, in bytes
+\end{itemize}
+
\section{Ur Syntax}
diff --git a/include/request.h b/include/request.h
index dd0359c9..a1a7d78d 100644
--- a/include/request.h
+++ b/include/request.h
@@ -32,4 +32,6 @@ typedef struct {
void *client_pruner(void *data);
+int pthread_create_big(pthread_t *outThread, void *foo, void *threadFunc, void *arg);
+
#endif
diff --git a/src/c/fastcgi.c b/src/c/fastcgi.c
index 161cb834..dcfdec78 100644
--- a/src/c/fastcgi.c
+++ b/src/c/fastcgi.c
@@ -569,7 +569,7 @@ int main(int argc, char *argv[]) {
{
pthread_t thread;
- if (pthread_create(&thread, NULL, client_pruner, &ls)) {
+ if (pthread_create_big(&thread, NULL, client_pruner, &ls)) {
fprintf(stderr, "Error creating pruner thread\n");
return 1;
}
@@ -578,7 +578,7 @@ int main(int argc, char *argv[]) {
for (i = 0; i < nthreads; ++i) {
pthread_t thread;
names[i] = i;
- if (pthread_create(&thread, NULL, worker, &names[i])) {
+ if (pthread_create_big(&thread, NULL, worker, &names[i])) {
fprintf(stderr, "Error creating worker thread #%d\n", i);
return 1;
}
diff --git a/src/c/http.c b/src/c/http.c
index 4b2f0576..df9d3080 100644
--- a/src/c/http.c
+++ b/src/c/http.c
@@ -311,7 +311,7 @@ int main(int argc, char *argv[]) {
{
pthread_t thread;
- if (pthread_create(&thread, NULL, client_pruner, &ls)) {
+ if (pthread_create_big(&thread, NULL, client_pruner, &ls)) {
fprintf(stderr, "Error creating pruner thread\n");
return 1;
}
@@ -320,7 +320,7 @@ int main(int argc, char *argv[]) {
for (i = 0; i < nthreads; ++i) {
pthread_t thread;
names[i] = i;
- if (pthread_create(&thread, NULL, worker, &names[i])) {
+ if (pthread_create_big(&thread, NULL, worker, &names[i])) {
fprintf(stderr, "Error creating worker thread #%d\n", i);
return 1;
}
diff --git a/src/c/request.c b/src/c/request.c
index 3fd12ff6..9f8cab36 100644
--- a/src/c/request.c
+++ b/src/c/request.c
@@ -123,12 +123,40 @@ static void *periodic_loop(void *data) {
};
}
+static unsigned long long stackSize;
+
+int pthread_create_big(pthread_t *outThread, void *foo, void *threadFunc, void *arg)
+{
+ int err;
+ pthread_attr_t stackSizeAttribute;
+
+ err = pthread_attr_init(&stackSizeAttribute);
+ if (err) return err;
+
+ if (stackSize > 0) {
+ err = pthread_attr_setstacksize(&stackSizeAttribute, stackSize);
+ if (err) return err;
+ }
+
+ return pthread_create(outThread, &stackSizeAttribute, threadFunc, arg);
+}
+
void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_logger log_debug) {
uw_context ctx;
failure_kind fk;
uw_periodic *ps;
loggers *ls = malloc(sizeof(loggers));
int id;
+ char *stackSize_s;
+
+ if ((stackSize_s = getenv("URWEB_STACK_SIZE")) != NULL && stackSize_s[0] != 0) {
+ stackSize = atoll(stackSize_s);
+
+ if (stackSize <= 0) {
+ fprintf(stderr, "Invalid stack size \"%s\"\n", stackSize_s);
+ exit(1);
+ }
+ }
ls->app = app;
ls->logger_data = logger_data;
@@ -141,7 +169,7 @@ void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_log
{
pthread_t thread;
- if (uw_time_max && pthread_create(&thread, NULL, ticker, NULL)) {
+ if (uw_time_max && pthread_create_big(&thread, NULL, ticker, NULL)) {
fprintf(stderr, "Error creating ticker thread\n");
exit(1);
}
@@ -174,7 +202,7 @@ void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_log
arg->ls = ls;
arg->pdic = *ps;
- if (pthread_create(&thread, NULL, periodic_loop, arg)) {
+ if (pthread_create_big(&thread, NULL, periodic_loop, arg)) {
fprintf(stderr, "Error creating periodic thread\n");
exit(1);
}
diff --git a/tests/overflow.ur b/tests/overflow.ur
new file mode 100644
index 00000000..09edc5a3
--- /dev/null
+++ b/tests/overflow.ur
@@ -0,0 +1,8 @@
+fun makeList n = if n = 0 then [] else 1 :: makeList (n - 1)
+
+fun doit {N = n} = return <xml><body>{[List.length (makeList (readError n))]}</body></xml>
+
+fun main () =
+ return <xml><body>
+ <form> <textbox{#N}/> <submit action={doit}/> </form>
+ </body></xml>
diff --git a/tests/overflow.urp b/tests/overflow.urp
new file mode 100644
index 00000000..d0913876
--- /dev/null
+++ b/tests/overflow.urp
@@ -0,0 +1,4 @@
+rewrite all Overflow/*
+
+$/list
+overflow
diff --git a/tests/overflow.urs b/tests/overflow.urs
new file mode 100644
index 00000000..6ac44e0b
--- /dev/null
+++ b/tests/overflow.urs
@@ -0,0 +1 @@
+val main : unit -> transaction page