That is how I fixed the problem. I didn't check all the consequences
of this fix.

2014-06-16 1:10 GMT+04:00 Sergey Mironov <[email protected]>:
> Hi! I've found a bug while debugging my FFI code!
>
> Look at the request() from request.c. It contains the following pattern:
>
>     ...
>     }
>     else if (fk == FATAL) {
>       log_error(logger_data, "Fatal error: %s\n", uw_error_message(ctx));
>
>       if (uw_get_app(ctx)->on_error && !had_error) {
>         had_error = 1;
>         strcpy(errmsg, uw_error_message(ctx));
>       } else {
>         uw_reset_keep_error_message(ctx);
>         on_failure(ctx);
>         uw_write_header(ctx, "Content-type: text/html\r\n");
>         uw_write(ctx, "<html><head><title>Fatal Error</title></head><body>");
>         uw_write(ctx, "Fatal error: ");
>         uw_write(ctx, uw_error_message(ctx));
>         uw_write(ctx, "\n</body></html>");
>
>         try_rollback(ctx, 0, logger_data, log_error);
>
>         return FAILED;
>       }
>     } else {
>     ...
>
> Note, that try_rollback() is executed _after_
> uw_reset_keep_error_message(). It is an error because reset will
> assign ctx->used_transactionals to 0 and prevent FFI cleanup handlers
> from working! Let me suggest calling try_rollback() before reset.
> Please, check!
>
> Regards,
> Sergey
>
> PS
> I didn't update the compiler up to the latest version yet.
# HG changeset patch
# User Sergey Mironov <[email protected]>
# Date 1402866792 0
#      Sun Jun 15 21:13:12 2014 +0000
# Node ID 1d070ac50b47c4f4591e021dcd439b3edec9224a
# Parent  14bcda785ad10356cf1aaf4bcdc1733a30bbf880
Call try_rollback before resetting the context

This will allow FFI cleanup handlers to complete.

diff --git a/src/c/request.c b/src/c/request.c
--- a/src/c/request.c
+++ b/src/c/request.c
@@ -503,14 +503,14 @@
           had_error = 1;
           strcpy(errmsg, uw_error_message(ctx));
         } else {
+          try_rollback(ctx, 0, logger_data, log_error);
+
           uw_write_header(ctx, "Content-type: text/html\r\n");
           uw_write(ctx, "<html><head><title>Fatal Error</title></head><body>");
           uw_write(ctx, "Fatal error: ");
           uw_write(ctx, uw_error_message(ctx));
           uw_write(ctx, "\n</body></html>");
         
-          try_rollback(ctx, 0, logger_data, log_error);
-
           return FAILED;
         }
       } else
@@ -527,14 +527,14 @@
           had_error = 1;
           strcpy(errmsg, uw_error_message(ctx));
         } else {
+          try_rollback(ctx, 0, logger_data, log_error);
+
           uw_reset_keep_error_message(ctx);
           on_failure(ctx);
           uw_write_header(ctx, "Content-type: text/plain\r\n");
           uw_write(ctx, "Fatal error (out of retries): ");
           uw_write(ctx, uw_error_message(ctx));
           uw_write(ctx, "\n");
-          
-          try_rollback(ctx, 0, logger_data, log_error);
 
           return FAILED;
         }
@@ -548,6 +548,8 @@
         had_error = 1;
         strcpy(errmsg, uw_error_message(ctx));
       } else {
+        try_rollback(ctx, 0, logger_data, log_error);
+
         uw_reset_keep_error_message(ctx);
         on_failure(ctx);
         uw_write_header(ctx, "Content-type: text/html\r\n");
@@ -556,8 +558,6 @@
         uw_write(ctx, uw_error_message(ctx));
         uw_write(ctx, "\n</body></html>");
 
-        try_rollback(ctx, 0, logger_data, log_error);
-
         return FAILED;
       }
     } else {
@@ -567,13 +567,13 @@
         had_error = 1;
         strcpy(errmsg, "Unknown uw_handle return code");
       } else {
+        try_rollback(ctx, 0, logger_data, log_error);
+
         uw_reset_keep_request(ctx);
         on_failure(ctx);
         uw_write_header(ctx, "Content-type: text/plain\r\n");
         uw_write(ctx, "Unknown uw_handle return code!\n");
 
-        try_rollback(ctx, 0, logger_data, log_error);
-
         return FAILED;
       }
     }
diff --git a/src/c/urweb.c b/src/c/urweb.c
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -3343,7 +3343,7 @@
           if (ctx->transactionals[i].free)
             ctx->transactionals[i].free(ctx->transactionals[i].data, 1);
 
-	return 1;
+        return 1;
       }
 
       for (i = ctx->used_transactionals-1; i >= 0; --i)
_______________________________________________
Ur mailing list
[email protected]
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur

Reply via email to