Permalink
Browse files

Block signals properly for a pile more API entry points

How'd I miss these???
  • Loading branch information...
1 parent c2a5062 commit ddc3121fc15e3d8f6bc3fdba0a3f7ed97cf41a8a @bos bos committed Jun 4, 2011
Showing with 62 additions and 22 deletions.
  1. +14 −7 Database/MySQL/Base.hs
  2. +19 −15 Database/MySQL/Base/C.hsc
  3. +25 −0 cbits/mysql_signals.c
  4. +4 −0 include/mysql_signals.h
@@ -204,6 +204,7 @@ data Result = Result {
, resFetchFields :: Ptr MYSQL_RES -> IO (Ptr Field)
, resFetchRow :: Ptr MYSQL_RES -> IO MYSQL_ROW
, resFetchLengths :: Ptr MYSQL_RES -> IO (Ptr CULong)
+ , resFreeResult :: Ptr MYSQL_RES -> IO ()
} | EmptyResult
-- | A row cursor, used by 'rowSeek' and 'rowTell'.
@@ -410,6 +411,7 @@ storeResult = frobResult "storeResult" mysql_store_result
mysql_fetch_fields_nonblock
mysql_fetch_row_nonblock
mysql_fetch_lengths_nonblock
+ mysql_free_result_nonblock
-- | Initiate a row-by-row retrieval of a result.
--
@@ -419,14 +421,17 @@ useResult = frobResult "useResult" mysql_use_result
mysql_fetch_fields
mysql_fetch_row
mysql_fetch_lengths
+ mysql_free_result
frobResult :: String
-> (Ptr MYSQL -> IO (Ptr MYSQL_RES))
-> (Ptr MYSQL_RES -> IO (Ptr Field))
-> (Ptr MYSQL_RES -> IO MYSQL_ROW)
-> (Ptr MYSQL_RES -> IO (Ptr CULong))
+ -> (Ptr MYSQL_RES -> IO ())
-> Connection -> IO Result
-frobResult func frob fetchFieldsFunc fetchRowFunc fetchLengthsFunc conn =
+frobResult func frob fetchFieldsFunc fetchRowFunc fetchLengthsFunc
+ myFreeResult conn =
withConn conn $ \ptr -> do
cleanupConnResult (connResult conn)
res <- frob ptr
@@ -437,7 +442,7 @@ frobResult func frob fetchFieldsFunc fetchRowFunc fetchLengthsFunc conn =
then return EmptyResult
else connectionError func conn
else do
- fp <- newForeignPtr res $ freeResult_ valid res
+ fp <- newForeignPtr res $ freeResult_ valid myFreeResult res
let ret = Result {
resFP = fp
, resFields = fromIntegral fields
@@ -446,15 +451,17 @@ frobResult func frob fetchFieldsFunc fetchRowFunc fetchLengthsFunc conn =
, resFetchFields = fetchFieldsFunc
, resFetchRow = fetchRowFunc
, resFetchLengths = fetchLengthsFunc
+ , resFreeResult = myFreeResult
}
- weak <- mkWeakPtr ret (Just (freeResult_ valid res))
+ weak <- mkWeakPtr ret (Just (freeResult_ valid myFreeResult res))
writeIORef (connResult conn) (Just weak)
return ret
-- | Immediately free the @MYSQL_RES@ value associated with this
-- 'Result', and mark the @Result@ as invalid.
freeResult :: Result -> IO ()
-freeResult Result{..} = withForeignPtr resFP $ freeResult_ resValid
+freeResult Result{..} = withForeignPtr resFP $
+ freeResult_ resValid resFreeResult
freeResult EmptyResult{..} = return ()
-- | Check whether a 'Result' is still valid, i.e. backed by a live
@@ -463,10 +470,10 @@ isResultValid :: Result -> IO Bool
isResultValid Result{..} = readIORef resValid
isResultValid EmptyResult = return False
-freeResult_ :: IORef Bool -> Ptr MYSQL_RES -> IO ()
-freeResult_ valid ptr = do
+freeResult_ :: IORef Bool -> (Ptr MYSQL_RES -> IO ()) -> Ptr MYSQL_RES -> IO ()
+freeResult_ valid free ptr = do
wasValid <- atomicModifyIORef valid $ \prev -> (False, prev)
- when wasValid $ mysql_free_result ptr
+ when wasValid $ free ptr
fetchRow :: Result -> IO [Maybe ByteString]
fetchRow res@Result{..} = withRes "fetchRow" res $ \ptr -> do
@@ -46,6 +46,7 @@ module Database.MySQL.Base.C
, mysql_fetch_row_nonblock
-- * Working with results
, mysql_free_result
+ , mysql_free_result_nonblock
, mysql_fetch_fields
, mysql_fetch_fields_nonblock
, mysql_data_seek
@@ -154,26 +155,26 @@ foreign import ccall safe mysql_ssl_set
-> CString -- ^ Ciphers.
-> IO MyBool
-foreign import ccall unsafe mysql_close
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_close" mysql_close
:: Ptr MYSQL -> IO ()
-foreign import ccall unsafe mysql_ping
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_ping" mysql_ping
:: Ptr MYSQL -> IO CInt
foreign import ccall safe mysql_thread_id
:: Ptr MYSQL -> IO CULong
-foreign import ccall unsafe mysql_autocommit
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_autocommit" mysql_autocommit
:: Ptr MYSQL -> MyBool -> IO MyBool
-foreign import ccall unsafe mysql_change_user
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_change_user" mysql_change_user
:: Ptr MYSQL
-> CString -- ^ user
-> CString -- ^ password
-> CString -- ^ database
-> IO MyBool
-foreign import ccall unsafe mysql_select_db
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_select_db" mysql_select_db
:: Ptr MYSQL
-> CString
-> IO CInt
@@ -196,7 +197,7 @@ foreign import ccall safe mysql_set_character_set
foreign import ccall safe mysql_get_ssl_cipher
:: Ptr MYSQL -> IO CString
-foreign import ccall unsafe mysql_stat
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_stat" mysql_stat
:: Ptr MYSQL -> IO CString
foreign import ccall unsafe "mysql_signals.h _hs_mysql_real_query" mysql_real_query
@@ -211,16 +212,19 @@ foreign import ccall safe mysql_field_count
foreign import ccall safe mysql_affected_rows
:: Ptr MYSQL -> IO CULLong
-foreign import ccall unsafe mysql_store_result
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_store_result" mysql_store_result
:: Ptr MYSQL -> IO (Ptr MYSQL_RES)
-foreign import ccall unsafe mysql_use_result
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_use_result" mysql_use_result
:: Ptr MYSQL -> IO (Ptr MYSQL_RES)
-foreign import ccall unsafe mysql_free_result
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_free_result" mysql_free_result
:: Ptr MYSQL_RES -> IO ()
-foreign import ccall unsafe mysql_fetch_fields
+foreign import ccall safe "mysql.h mysql_free_result" mysql_free_result_nonblock
+ :: Ptr MYSQL_RES -> IO ()
+
+foreign import ccall safe mysql_fetch_fields
:: Ptr MYSQL_RES -> IO (Ptr Field)
foreign import ccall safe "mysql.h mysql_fetch_fields" mysql_fetch_fields_nonblock
@@ -235,22 +239,22 @@ foreign import ccall safe mysql_row_seek
foreign import ccall safe mysql_row_tell
:: Ptr MYSQL_RES -> IO MYSQL_ROW_OFFSET
-foreign import ccall unsafe mysql_next_result
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_next_result" mysql_next_result
:: Ptr MYSQL -> IO CInt
-foreign import ccall unsafe mysql_commit
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_commit" mysql_commit
:: Ptr MYSQL -> IO MyBool
-foreign import ccall unsafe mysql_rollback
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_rollback" mysql_rollback
:: Ptr MYSQL -> IO MyBool
-foreign import ccall unsafe mysql_fetch_row
+foreign import ccall unsafe "mysql_signals.h _hs_mysql_fetch_row" mysql_fetch_row
:: Ptr MYSQL_RES -> IO MYSQL_ROW
foreign import ccall safe "mysql.h mysql_fetch_row" mysql_fetch_row_nonblock
:: Ptr MYSQL_RES -> IO MYSQL_ROW
-foreign import ccall unsafe mysql_fetch_lengths
+foreign import ccall safe mysql_fetch_lengths
:: Ptr MYSQL_RES -> IO (Ptr CULong)
foreign import ccall safe "mysql.h mysql_fetch_lengths" mysql_fetch_lengths_nonblock
View
@@ -85,6 +85,24 @@ const char *STDCALL _hs_mysql_stat(MYSQL *mysql)
return ret;
}
+my_bool STDCALL _hs_mysql_commit(MYSQL * mysql)
+{
+ my_bool ret;
+ block_rts_signals();
+ ret = mysql_commit(mysql);
+ unblock_rts_signals();
+ return ret;
+}
+
+my_bool STDCALL _hs_mysql_rollback(MYSQL * mysql)
+{
+ my_bool ret;
+ block_rts_signals();
+ ret = mysql_rollback(mysql);
+ unblock_rts_signals();
+ return ret;
+}
+
my_bool STDCALL _hs_mysql_autocommit(MYSQL *mysql, my_bool auto_mode)
{
my_bool ret;
@@ -158,6 +176,13 @@ MYSQL_RES *STDCALL _hs_mysql_use_result(MYSQL *mysql)
return ret;
}
+void STDCALL _hs_mysql_free_result(MYSQL_RES *result)
+{
+ block_rts_signals();
+ mysql_free_result(result);
+ unblock_rts_signals();
+}
+
int STDCALL _hs_mysql_next_result(MYSQL *mysql)
{
int ret;
@@ -20,6 +20,8 @@ int STDCALL _hs_mysql_ping(MYSQL *mysql);
int STDCALL _hs_mysql_real_query(MYSQL *mysql, const char *q,
unsigned long length);
const char *STDCALL _hs_mysql_stat(MYSQL *mysql);
+my_bool STDCALL _hs_mysql_commit(MYSQL * mysql);
+my_bool STDCALL _hs_mysql_rollback(MYSQL * mysql);
my_bool STDCALL _hs_mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool STDCALL _hs_mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db);
@@ -29,6 +31,8 @@ MYSQL_ROW STDCALL _hs_mysql_fetch_row(MYSQL_RES *result);
unsigned long *STDCALL _hs_mysql_fetch_lengths(MYSQL_RES *result);
MYSQL_RES *STDCALL _hs_mysql_store_result(MYSQL *mysql);
MYSQL_RES *STDCALL _hs_mysql_use_result(MYSQL *mysql);
+void STDCALL _hs_mysql_free_result(MYSQL_RES *result);
int STDCALL _hs_mysql_next_result(MYSQL *mysql);
+void STDCALL _hs_mysql_close(MYSQL *sock);
#endif /* _mysql_signals_h */

0 comments on commit ddc3121

Please sign in to comment.