@@ -2373,6 +2373,21 @@ loUnlink connection oid
2373
2373
negError =<< c_lo_unlink c oid
2374
2374
2375
2375
2376
+ -- Reminder on `unsafe` FFI:
2377
+ --
2378
+ -- - `unsafe` calls MUST NOT do any blocking IO!
2379
+ -- - `unsafe` calls MUST NOT call back into Haskell!
2380
+ -- Otherwise the program may hang permanently.
2381
+ --
2382
+ -- Here is an example of the seemingly innocent function `PQisBusy()`
2383
+ -- actually calling back into Haskell in some cases:
2384
+ -- `PQisBusy()` in some cases calls `pqParseInput3()`
2385
+ -- which calls `pqGetErrorNotice3()` which can call back into a
2386
+ -- user-defined error notice processing callback if set,
2387
+ -- which the user might have set to be a Haskell function.
2388
+ --
2389
+ -- See https://downloads.haskell.org/ghc/9.2.2/docs/html/users_guide/exts/ffi.html#foreign-imports-and-multi-threading
2390
+ -- for details.
2376
2391
2377
2392
foreign import ccall " libpq-fe.h PQconnectdb"
2378
2393
c_PQconnectdb :: CString -> IO (Ptr PGconn )
@@ -2383,51 +2398,66 @@ foreign import ccall "libpq-fe.h PQconnectStart"
2383
2398
foreign import ccall " libpq-fe.h PQconnectPoll"
2384
2399
c_PQconnectPoll :: Ptr PGconn -> IO CInt
2385
2400
2401
+ -- | `unsafe` is OK because `PQdb` calls no functions.
2386
2402
foreign import ccall unsafe " libpq-fe.h PQdb"
2387
2403
c_PQdb :: Ptr PGconn -> IO CString
2388
2404
2405
+ -- | `unsafe` is OK because `PQuser` calls no functions.
2389
2406
foreign import ccall unsafe " libpq-fe.h PQuser"
2390
2407
c_PQuser :: Ptr PGconn -> IO CString
2391
2408
2409
+ -- | `unsafe` is OK because `PQpass` calls no functions.
2392
2410
foreign import ccall unsafe " libpq-fe.h PQpass"
2393
2411
c_PQpass :: Ptr PGconn -> IO CString
2394
2412
2413
+ -- | `unsafe` is OK because `PQhost` calls no functions.
2395
2414
foreign import ccall unsafe " libpq-fe.h PQhost"
2396
2415
c_PQhost :: Ptr PGconn -> IO CString
2397
2416
2417
+ -- | `unsafe` is OK because `PQport` calls no functions.
2398
2418
foreign import ccall unsafe " libpq-fe.h PQport"
2399
2419
c_PQport :: Ptr PGconn -> IO CString
2400
2420
2421
+ -- | `unsafe` is OK because `PQport` calls no functions.
2401
2422
foreign import ccall unsafe " libpq-fe.h PQoptions"
2402
2423
c_PQoptions :: Ptr PGconn -> IO CString
2403
2424
2425
+ -- | `unsafe` is OK because `PQbackendPID` calls no functions.
2404
2426
foreign import ccall unsafe " libpq-fe.h PQbackendPID"
2405
2427
c_PQbackendPID :: Ptr PGconn -> IO CInt
2406
2428
2429
+ -- | `unsafe` is OK because `PQconnectionNeedsPassword` calls no functions
2430
+ -- (it calls `PQpass`, which does the same).
2407
2431
foreign import ccall unsafe " libpq-fe.h PQconnectionNeedsPassword"
2408
2432
c_PQconnectionNeedsPassword :: Ptr PGconn -> IO CInt
2409
2433
2434
+ -- | `unsafe` is OK because `PQconnectionUsedPassword` calls no functions.
2410
2435
foreign import ccall unsafe " libpq-fe.h PQconnectionUsedPassword"
2411
2436
c_PQconnectionUsedPassword :: Ptr PGconn -> IO CInt
2412
2437
2438
+ -- | `unsafe` is OK because `PQstatus` calls no functions.
2413
2439
foreign import ccall unsafe " libpq-fe.h PQstatus"
2414
2440
c_PQstatus :: Ptr PGconn -> IO CInt
2415
2441
2442
+ -- | `unsafe` is OK because `PQtransactionStatus` calls no functions.
2416
2443
foreign import ccall unsafe " libpq-fe.h PQtransactionStatus"
2417
2444
c_PQtransactionStatus :: Ptr PGconn -> IO CInt
2418
2445
2419
2446
foreign import ccall " libpq-fe.h PQparameterStatus"
2420
2447
c_PQparameterStatus :: Ptr PGconn -> CString -> IO CString
2421
2448
2449
+ -- | `unsafe` is OK because `PQprotocolVersion` calls no functions.
2422
2450
foreign import ccall unsafe " libpq-fe.h PQprotocolVersion"
2423
2451
c_PQprotocolVersion :: Ptr PGconn -> IO CInt
2424
2452
2453
+ -- | `unsafe` is OK because `PQserverVersion` calls no functions.
2425
2454
foreign import ccall unsafe " libpq-fe.h PQserverVersion"
2426
2455
c_PQserverVersion :: Ptr PGconn -> IO CInt
2427
2456
2428
2457
foreign import ccall " dynamic"
2429
2458
mkLibpqVersion :: FunPtr Int -> Int
2430
2459
2460
+ -- | `unsafe` is OK because `PQsocket` calls no functions.
2431
2461
foreign import ccall unsafe " libpq-fe.h PQsocket"
2432
2462
c_PQsocket :: Ptr PGconn -> IO CInt
2433
2463
@@ -2451,6 +2481,7 @@ foreign import ccall "libpq-fe.h PQresetStart"
2451
2481
foreign import ccall " libpq-fe.h PQresetPoll"
2452
2482
c_PQresetPoll :: Ptr PGconn -> IO CInt
2453
2483
2484
+ -- | `unsafe` is OK because `PQclientEncoding` calls no functions.
2454
2485
foreign import ccall unsafe " libpq-fe.h PQclientEncoding"
2455
2486
c_PQclientEncoding :: Ptr PGconn -> IO CInt
2456
2487
@@ -2461,6 +2492,7 @@ foreign import ccall "libpq-fe.h PQsetClientEncoding"
2461
2492
c_PQsetClientEncoding :: Ptr PGconn -> CString -> IO CInt
2462
2493
2463
2494
type PGVerbosity = CInt
2495
+ -- | `unsafe` is OK because `PQclientEncoding` calls no functions.
2464
2496
foreign import ccall unsafe " libpq-fe.h PQsetErrorVerbosity"
2465
2497
c_PQsetErrorVerbosity :: Ptr PGconn -> PGVerbosity -> IO PGVerbosity
2466
2498
@@ -2507,21 +2539,23 @@ foreign import ccall "libpq-fe.h &PQfreeCancel"
2507
2539
foreign import ccall " libpq-fe.h PQcancel"
2508
2540
c_PQcancel :: Ptr PGcancel -> CString -> CInt -> IO CInt
2509
2541
2510
- foreign import ccall unsafe " libpq-fe.h PQnotifies"
2542
+ foreign import ccall " libpq-fe.h PQnotifies"
2511
2543
c_PQnotifies :: Ptr PGconn -> IO (Ptr Notify )
2512
2544
2513
2545
foreign import ccall " libpq-fe.h PQconsumeInput"
2514
2546
c_PQconsumeInput :: Ptr PGconn -> IO CInt
2515
2547
2516
- foreign import ccall unsafe " libpq-fe.h PQisBusy"
2548
+ foreign import ccall " libpq-fe.h PQisBusy"
2517
2549
c_PQisBusy :: Ptr PGconn -> IO CInt
2518
2550
2519
2551
foreign import ccall " libpq-fe.h PQsetnonblocking"
2520
2552
c_PQsetnonblocking :: Ptr PGconn -> CInt -> IO CInt
2521
2553
2554
+ -- | `unsafe` is OK because `PQisnonblocking` calls only a macro that calls no functions.
2522
2555
foreign import ccall unsafe " libpq-fe.h PQisnonblocking"
2523
2556
c_PQisnonblocking :: Ptr PGconn -> IO CInt
2524
2557
2558
+ -- | `unsafe` is OK because `PQsetSingleRowMode` calls no functions.
2525
2559
foreign import ccall unsafe " libpq-fe.h PQsetSingleRowMode"
2526
2560
c_PQsetSingleRowMode :: Ptr PGconn -> IO CInt
2527
2561
@@ -2553,67 +2587,91 @@ foreign import ccall "libpq-fe.h PQdescribePortal"
2553
2587
foreign import ccall " libpq-fe.h &PQclear"
2554
2588
p_PQclear :: FunPtr (Ptr PGresult -> IO () )
2555
2589
2590
+ -- | `unsafe` is OK because `PQresultStatus` calls no functions.
2556
2591
foreign import ccall unsafe " libpq-fe.h PQresultStatus"
2557
2592
c_PQresultStatus :: Ptr PGresult -> IO CInt
2558
2593
2559
- foreign import ccall unsafe " libpq-fe.h PQresStatus"
2594
+ -- Must not be `unsafe` because `PQresStatus` may use `libpq_gettext()` that may do IO.
2595
+ foreign import ccall " libpq-fe.h PQresStatus"
2560
2596
c_PQresStatus :: CInt -> IO CString
2561
2597
2598
+ -- | `unsafe` is OK because `PQresultStatus` calls no functions.
2562
2599
foreign import ccall unsafe " libpq-fe.h PQresultErrorMessage"
2563
2600
c_PQresultErrorMessage :: Ptr PGresult -> IO CString
2564
2601
2565
2602
foreign import ccall " libpq-fe.h PQresultErrorField"
2566
2603
c_PQresultErrorField :: Ptr PGresult -> CInt -> IO CString
2567
2604
2605
+ -- | `unsafe` is OK because `PQntuples` calls no functions.
2568
2606
foreign import ccall unsafe " libpq-fe.h PQntuples"
2569
2607
c_PQntuples :: Ptr PGresult -> CInt
2570
2608
2609
+ -- | `unsafe` is OK because `PQnfields` calls no functions.
2571
2610
foreign import ccall unsafe " libpq-fe.h PQnfields"
2572
2611
c_PQnfields :: Ptr PGresult -> CInt
2573
2612
2574
- foreign import ccall unsafe " libpq-fe.h PQfname"
2613
+ -- Must not be `unsafe` because `PQfname` may call `check_field_number()` which may call `pqInternalNotice()`.
2614
+ foreign import ccall " libpq-fe.h PQfname"
2575
2615
c_PQfname :: Ptr PGresult -> CInt -> IO CString
2576
2616
2617
+ -- | `unsafe` is OK because `PQfnumber` calls only `pg_tolower()`, which calls
2618
+ -- only C stdlib functions that certainly will not call back into Haskell.
2619
+ -- Note `pg_tolower()` also calls `strdup()` and `free()`, so if one of those
2620
+ -- was overridden with e.g. glibc hooks to call back into Haskell, this would be wrong.
2621
+ -- However, these functions are generally considered to not call back into Haskell.
2577
2622
foreign import ccall unsafe " libpq-fe.h PQfnumber"
2578
2623
c_PQfnumber :: Ptr PGresult -> CString -> IO CInt
2579
2624
2580
- foreign import ccall unsafe " libpq-fe.h PQftable"
2625
+ -- Must not be `unsafe` because `PQftable` may call `check_field_number()` which may call `pqInternalNotice()`.
2626
+ foreign import ccall " libpq-fe.h PQftable"
2581
2627
c_PQftable :: Ptr PGresult -> CInt -> IO Oid
2582
2628
2583
- foreign import ccall unsafe " libpq-fe.h PQftablecol"
2629
+ -- Must not be `unsafe` because `PQftablecol` may call `check_field_number()` which may call `pqInternalNotice()`.
2630
+ foreign import ccall " libpq-fe.h PQftablecol"
2584
2631
c_PQftablecol :: Ptr PGresult -> CInt -> IO CInt
2585
2632
2586
- foreign import ccall unsafe " libpq-fe.h PQfformat"
2633
+ -- Must not be `unsafe` because `PQfformat` may call `check_field_number()` which may call `pqInternalNotice()`.
2634
+ foreign import ccall " libpq-fe.h PQfformat"
2587
2635
c_PQfformat :: Ptr PGresult -> CInt -> IO CInt
2588
2636
2637
+ -- Must not be `unsafe` because `PQftype` may call `check_field_number()` which may call `pqInternalNotice()`.
2589
2638
foreign import ccall unsafe " libpq-fe.h PQftype"
2590
2639
c_PQftype :: Ptr PGresult -> CInt -> IO Oid
2591
2640
2592
- foreign import ccall unsafe " libpq-fe.h PQfmod"
2641
+ -- Must not be `unsafe` because `PQfmod` may call `check_field_number()` which may call `pqInternalNotice()`.
2642
+ foreign import ccall " libpq-fe.h PQfmod"
2593
2643
c_PQfmod :: Ptr PGresult -> CInt -> IO CInt
2594
2644
2595
- foreign import ccall unsafe " libpq-fe.h PQfsize"
2645
+ -- Must not be `unsafe` because `PQfsize` may call `check_field_number()` which may call `pqInternalNotice()`.
2646
+ foreign import ccall " libpq-fe.h PQfsize"
2596
2647
c_PQfsize :: Ptr PGresult -> CInt -> IO CInt
2597
2648
2598
- foreign import ccall unsafe " libpq-fe.h PQgetvalue"
2649
+ -- Must not be `unsafe` because `PQgetvalue` may call `check_tuple_field_number()` which may call `pqInternalNotice()`.
2650
+ foreign import ccall " libpq-fe.h PQgetvalue"
2599
2651
c_PQgetvalue :: Ptr PGresult -> CInt -> CInt -> IO CString
2600
2652
2601
- foreign import ccall unsafe " libpq-fe.h PQgetisnull"
2653
+ -- Must not be `unsafe` because `PQgetisnull` may call `check_tuple_field_number()` which may call `pqInternalNotice()`.
2654
+ foreign import ccall " libpq-fe.h PQgetisnull"
2602
2655
c_PQgetisnull :: Ptr PGresult -> CInt -> CInt -> IO CInt
2603
2656
2604
- foreign import ccall unsafe " libpq-fe.h PQgetlength"
2657
+ -- Must not be `unsafe` because `PQgetlength` may call `check_tuple_field_number()` which may call `pqInternalNotice()`.
2658
+ foreign import ccall " libpq-fe.h PQgetlength"
2605
2659
c_PQgetlength :: Ptr PGresult -> CInt -> CInt -> IO CInt
2606
2660
2661
+ -- | `unsafe` is OK because `PQnparams` calls no functions.
2607
2662
foreign import ccall unsafe " libpq-fe.h PQnparams"
2608
2663
c_PQnparams :: Ptr PGresult -> IO CInt
2609
2664
2610
- foreign import ccall unsafe " libpq-fe.h PQparamtype"
2665
+ -- Must not be `unsafe` because `PQparamtype` may call `check_param_number()` which may call `pqInternalNotice()`.
2666
+ foreign import ccall " libpq-fe.h PQparamtype"
2611
2667
c_PQparamtype :: Ptr PGresult -> CInt -> IO Oid
2612
2668
2669
+ -- | `unsafe` is OK because `PQcmdStatus` calls no functions.
2613
2670
foreign import ccall unsafe " libpq-fe.h PQcmdStatus"
2614
2671
c_PQcmdStatus :: Ptr PGresult -> IO CString
2615
2672
2616
- foreign import ccall unsafe " libpq-fe.h PQcmdTuples"
2673
+ -- Must not be `unsafe` because `PQcmdTuples` may call `pqInternalNotice()`.
2674
+ foreign import ccall " libpq-fe.h PQcmdTuples"
2617
2675
c_PQcmdTuples :: Ptr PGresult -> IO CString
2618
2676
2619
2677
foreign import ccall " libpq-fe.h PQescapeStringConn"
@@ -2636,33 +2694,42 @@ foreign import ccall "libpq-fe.h PQunescapeBytea"
2636
2694
-> Ptr CSize
2637
2695
-> IO (Ptr Word8 ) -- Actually (IO (Ptr CUChar))
2638
2696
2639
- foreign import ccall unsafe " libpq-fe.h PQescapeIdentifier"
2697
+ -- Must not be `unsafe` because `PQescapeIdentifier` may call `libpq_gettext()` that may do IO.
2698
+ foreign import ccall " libpq-fe.h PQescapeIdentifier"
2640
2699
c_PQescapeIdentifier :: Ptr PGconn
2641
2700
-> CString
2642
2701
-> CSize
2643
2702
-> IO CString
2644
2703
2704
+ -- | `unsafe` is OK because `PQfreemem` only calls `free()`.
2645
2705
foreign import ccall unsafe " libpq-fe.h &PQfreemem"
2646
2706
p_PQfreemem :: FunPtr (Ptr a -> IO () )
2647
2707
2708
+ -- | `unsafe` is OK because `PQfreemem` only calls `free()`.
2648
2709
foreign import ccall unsafe " libpq-fe.h PQfreemem"
2649
2710
c_PQfreemem :: Ptr a -> IO ()
2650
2711
2712
+ -- | `unsafe` is OK because `hs_postgresql_libpq_malloc_noticebuffer` only calls `malloc()`.
2651
2713
foreign import ccall unsafe " noticehandlers.h hs_postgresql_libpq_malloc_noticebuffer"
2652
2714
c_malloc_noticebuffer :: IO (Ptr CNoticeBuffer )
2653
2715
2716
+ -- | `unsafe` is OK because `hs_postgresql_libpq_malloc_noticebuffer` only calls `free()`.
2654
2717
foreign import ccall unsafe " noticehandlers.h hs_postgresql_libpq_free_noticebuffer"
2655
2718
c_free_noticebuffer :: Ptr CNoticeBuffer -> IO ()
2656
2719
2720
+ -- | `unsafe` is OK because `hs_postgresql_libpq_get_notice` calls no functions.
2657
2721
foreign import ccall unsafe " noticehandlers.h hs_postgresql_libpq_get_notice"
2658
2722
c_get_notice :: Ptr CNoticeBuffer -> IO (Ptr PGnotice )
2659
2723
2724
+ -- | `unsafe` is OK because `hs_postgresql_libpq_discard_notices` calls no functions.
2660
2725
foreign import ccall unsafe " noticehandlers.h &hs_postgresql_libpq_discard_notices"
2661
2726
p_discard_notices :: FunPtr NoticeReceiver
2662
2727
2728
+ -- | `unsafe` is OK because `hs_postgresql_libpq_store_notices` calls only `PQresultErrorMessage`, which calls no functions.
2663
2729
foreign import ccall unsafe " noticehandlers.h &hs_postgresql_libpq_store_notices"
2664
2730
p_store_notices :: FunPtr NoticeReceiver
2665
2731
2732
+ -- | `unsafe` is OK because `PQsetNoticeReceiver` calls no functions.
2666
2733
foreign import ccall unsafe " libpq-fe.h PQsetNoticeReceiver"
2667
2734
c_PQsetNoticeReceiver :: Ptr PGconn -> FunPtr NoticeReceiver -> Ptr CNoticeBuffer -> IO (FunPtr NoticeReceiver )
2668
2735
0 commit comments