[plt-scheme] Cleanup on Servlet Timeout (Again)

From: Henk Boom (lunarc.lists at gmail.com)
Date: Thu Aug 28 15:07:36 EDT 2008

On 2008-08-28, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> At Thu, 28 Aug 2008 00:09:36 -0400, "Henk Boom" wrote:
>  > A separate issue is cleaning up sqlite resources allocated during
>  > reading/writing. I use prepared statements as a simple means to guard
>  > against SQL injection attacks, as they separate code from data in an
>  > SQL query. For example, to do a select query I actually have the
>  > following:
>  >
>  > (define (prepared-select query . params)
>  >   (let ((statement (prepare db query)))
>  >     (dynamic-wind
>  >       void
>  >       (lambda ()
>  >         (apply load-params statement params)
>  >         (step* statement))
>  >       (lambda () (finalize statement)))))
>  >
>  > The kicker is that if the statement is not finalized, the sqlite
>  > transaction will fail to close, so if a thread is terminated at the
>  > wrong time I could lose access to my database. I could let the server
>  > handle this whole process as well, but that doesn't sound like the
>  > right solution to the problem.
> Why not?

Simply because this feels like an atomicity problem rather than a
synchronization problem. Not really an important reason, but an
intuitive one.

>  More generally, you could run it in any thread that has the same
>  capability to run as the server thread --- perhaps another thread that
>  is created when the web server is started.

Except that if it's not atomic I have to make sure that the monitor
doesn't attempt to close the transaction while the query is running,
so I either need to use the same thread or introduce a new lock. I
think using the same thread is the simpler solution.

Important question: what is the overhead of blocking on inter-process
communication? I'm guessing it's much less than the time it takes to
make the database query, so it would be OK to use this every time, but
I don't know.

>  A comment on your version of the code: A writer posts to `fail-s' even
>  after succeeding and posting to `done-s'. When both semaphores are
>  posted, there's no guarantee that the server will see `done-s' before
>  `fail-s', since it `sync's on both at the same time. That is, if both
>  are available before the server actually picks (perhaps even before the
>  server manages to call the `sync' function), then it might pick
>  `fail-s' even though `done-s' is available.

Right, thanks. I was planning on checking the status of done-s when
handling the fail-s event, but I forgot. Now that I think about it,
that would be unintuitive behaviour for fail-s, so I've changed it to
set! fail-s to #f after posting done-s so that I know not to post it
as well.

>  Also, you still need to use something like `reply' instead of
>  `channel-put' to accept a reader/writer, but I think you know about
>  that problem (and probably you're waiting to create a test that
>  demonstrates the problem before fixing it).

I'm curious about the behaviour of this, so I'd like to try it out.
Wouldn't the same sort of delays happen when trying to send through a
channel to the server? (Obviously the same workaround does not work in
that case)


Posted on the users mailing list.