Re: [Haskell-cafe] Killing threads in foreign calls.

2011-04-18 Thread Gregory Collins
On Mon, Apr 18, 2011 at 12:48 AM, Jason Dusek jason.du...@gmail.com wrote:
  I gather I need to write the busy loop for polling for data in
  Haskell. Although libpq has a procedure -- PGgetResult -- that
  polls for data, it would not respond to killThread.

Please don't use a busy loop! Instead use PQSocket() to get the
underlying socket file descriptor, and call
ThreadWaitRead/ThreadWaitWrite to use the system event dispatcher
(epoll() or select()) to efficiently multiplex.

G
-- 
Gregory Collins g...@gregorycollins.net

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Killing threads in foreign calls.

2011-04-17 Thread Jason Dusek
  I am building an application that uses Postgres for storage.
  If a query runs too long, I would like to kill the querying
  thread, releasing its lock on the connection; if the
  connection is a in a bad state -- for example, busy -- I would
  like to clean up the connection.

  Unfortunately, killing calls in to libpq seems not to work. I
  have put a minimal example on hpaste:

http://hpaste.org/45774/minimal_pg_contention_example

  If you install libpq with Cabal, you can run it. In the
  example, the main thread spawns a worker thread that queries
  Postgres, running SELECT pg_sleep(10);; the main thread
  waits half a second and then tries to kill the worker.
  Unfortunately, the worker always manages to get as far as
  printing complete.

  In the code, I call `Database.PQ.exec':


http://hackage.haskell.org/packages/archive/libpq/0.4.1/doc/html/src/Database-PQ.html#exec

  This in turn calls a `safe' binding, `c_PQexec', to `PQexec'
  in the C library:


http://hackage.haskell.org/packages/archive/libpq/0.4.1/doc/html/src/Database-PQ.html#line-

  There are async interfaces, too; they do not seem to be any
  more killable then the sync ones.

  Maybe the problem is that you can't kill a thread while it's
  in a foreign call? I do not see any documentation to this
  effect; but I may have missed it.

--
Jason Dusek
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Killing threads in foreign calls.

2011-04-17 Thread Edward Z. Yang
This is a fairly nontrivial problem.  First off, let me tell you
what you do not /actually/ want to happen: you don't want the OS
level thread performing the foreign call to actually be killed;
most C code is not written a way that can gracefully recover from
this, and unless you have explicit indications from the Postgres
library that it use pthread_setcancelstate (and you, of course,
have the cross-platform issue.)

You need some way of making the Postgres call return early, with
an error code of some sort.  If Postgres has a signal handler
that does this, you can use something along the lines
of here: http://blog.ezyang.com/2010/11/its-just-a-longjmp-to-the-left/

If the asynchronous API has the ability to cancel a query given
some handler, you instead want to set up a custom kill thread function
that checks if a thread has an active query and then performs
another FFI call to perform that cancellation.

If the library doesn't have a way of doing graceful cancellation,
you're kind of out of luck.  Unfortunately there is no golden
touch for making this work.

Cheers,
Edward

Excerpts from Jason Dusek's message of Sun Apr 17 15:31:11 -0400 2011:
   I am building an application that uses Postgres for storage.
   If a query runs too long, I would like to kill the querying
   thread, releasing its lock on the connection; if the
   connection is a in a bad state -- for example, busy -- I would
   like to clean up the connection.
 
   Unfortunately, killing calls in to libpq seems not to work. I
   have put a minimal example on hpaste:
 
 http://hpaste.org/45774/minimal_pg_contention_example
 
   If you install libpq with Cabal, you can run it. In the
   example, the main thread spawns a worker thread that queries
   Postgres, running SELECT pg_sleep(10);; the main thread
   waits half a second and then tries to kill the worker.
   Unfortunately, the worker always manages to get as far as
   printing complete.
 
   In the code, I call `Database.PQ.exec':
 
 
 http://hackage.haskell.org/packages/archive/libpq/0.4.1/doc/html/src/Database-PQ.html#exec
 
   This in turn calls a `safe' binding, `c_PQexec', to `PQexec'
   in the C library:
 
 
 http://hackage.haskell.org/packages/archive/libpq/0.4.1/doc/html/src/Database-PQ.html#line-
 
   There are async interfaces, too; they do not seem to be any
   more killable then the sync ones.
 
   Maybe the problem is that you can't kill a thread while it's
   in a foreign call? I do not see any documentation to this
   effect; but I may have missed it.
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Killing threads in foreign calls.

2011-04-17 Thread Jason Dusek
On Sun, Apr 17, 2011 at 20:26, Edward Z. Yang ezy...@mit.edu wrote:
 This is a fairly nontrivial problem.  First off, let me tell you
 what you do not /actually/ want to happen: you don't want the OS
 level thread performing the foreign call to actually be killed...

  From this I gather, one can not generally kill Haskell threads
  while they are in the midst of foreign calls. I guess
  interrupting execution to terminate the program is special
  since you don't expect anything to work properly afterward.

 If the asynchronous API has the ability to cancel a query given
 some handler, you instead want to set up a custom kill thread function
 that checks if a thread has an active query and then performs
 another FFI call to perform that cancellation.

  It turns out the PGcancel exists for this purpose. Is it safe
  and reasonable to make query cancellation a ThreadKilled
  handler in the query thread?

  I gather I need to write the busy loop for polling for data in
  Haskell. Although libpq has a procedure -- PGgetResult -- that
  polls for data, it would not respond to killThread.

--
Jason Dusek
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe