diff --git a/Data/Complex.hs b/Data/Complex.hs
--- a/Data/Complex.hs
+++ b/Data/Complex.hs
@@ -50,17 +50,41 @@
 -- -----------------------------------------------------------------------------
 -- The Complex type
 
--- | Complex numbers are an algebraic type.
+-- | A data type representing complex numbers.
 --
--- For a complex number @z@, @'abs' z@ is a number with the magnitude of @z@,
--- but oriented in the positive real direction, whereas @'signum' z@
--- has the phase of @z@, but unit magnitude.
+-- You can read about complex numbers [on wikipedia](https://en.wikipedia.org/wiki/Complex_number).
 --
--- The 'Foldable' and 'Traversable' instances traverse the real part first.
+-- In haskell, complex numbers are represented as @a :+ b@ which can be thought of
+-- as representing \(a + bi\). For a complex number @z@, @'abs' z@ is a number with the 'magnitude' of @z@,
+-- but oriented in the positive real direction, whereas @'signum' z@
+-- has the 'phase' of @z@, but unit 'magnitude'.
+-- Apart from the loss of precision due to IEEE754 floating point numbers,
+-- it holds that @z == 'abs' z * 'signum' z@.
 --
 -- Note that `Complex`'s instances inherit the deficiencies from the type
 -- parameter's. For example, @Complex Float@'s 'Ord' instance has similar
 -- problems to `Float`'s.
+--
+-- As can be seen in the examples, the 'Foldable'
+-- and 'Traversable' instances traverse the real part first.
+--
+-- ==== __Examples__
+--
+-- >>> (5.0 :+ 2.5) + 6.5
+-- 11.5 :+ 2.5
+--
+-- >>> abs (1.0 :+ 1.0) - sqrt 2.0
+-- 0.0 :+ 0.0
+--
+-- >>> abs (signum (4.0 :+ 3.0))
+-- 1.0 :+ 0.0
+--
+-- >>> foldr (:) [] (1 :+ 2)
+-- [1,2]
+--
+-- >>> mapM print (1 :+ 2)
+-- 1
+-- 2
 data Complex a
   = !a :+ !a    -- ^ forms a complex number from its real and imaginary
                 -- rectangular components.
@@ -79,38 +103,113 @@
 -- Functions over Complex
 
 -- | Extracts the real part of a complex number.
+--
+-- ==== __Examples__
+--
+-- >>> realPart (5.0 :+ 3.0)
+-- 5.0
+--
+-- >>> realPart ((5.0 :+ 3.0) * (2.0 :+ 3.0))
+-- 1.0
 realPart :: Complex a -> a
 realPart (x :+ _) =  x
 
 -- | Extracts the imaginary part of a complex number.
+--
+-- ==== __Examples__
+--
+-- >>> imagPart (5.0 :+ 3.0)
+-- 3.0
+--
+-- >>> imagPart ((5.0 :+ 3.0) * (2.0 :+ 3.0))
+-- 21.0
 imagPart :: Complex a -> a
 imagPart (_ :+ y) =  y
 
--- | The conjugate of a complex number.
+-- | The 'conjugate' of a complex number.
+--
+-- prop> conjugate (conjugate x) = x
+--
+-- ==== __Examples__
+--
+-- >>> conjugate (3.0 :+ 3.0)
+-- 3.0 :+ (-3.0)
+--
+-- >>> conjugate ((3.0 :+ 3.0) * (2.0 :+ 2.0))
+-- 0.0 :+ (-12.0)
 {-# SPECIALISE conjugate :: Complex Double -> Complex Double #-}
 conjugate        :: Num a => Complex a -> Complex a
 conjugate (x:+y) =  x :+ (-y)
 
--- | Form a complex number from polar components of magnitude and phase.
+-- | Form a complex number from 'polar' components of 'magnitude' and 'phase'.
+--
+-- ==== __Examples__
+--
+-- >>> mkPolar 1 (pi / 4)
+-- 0.7071067811865476 :+ 0.7071067811865475
+--
+-- >>> mkPolar 1 0
+-- 1.0 :+ 0.0
 {-# SPECIALISE mkPolar :: Double -> Double -> Complex Double #-}
 mkPolar          :: Floating a => a -> a -> Complex a
 mkPolar r theta  =  r * cos theta :+ r * sin theta
 
--- | @'cis' t@ is a complex value with magnitude @1@
--- and phase @t@ (modulo @2*'pi'@).
+-- | @'cis' t@ is a complex value with 'magnitude' @1@
+-- and 'phase' @t@ (modulo @2*'pi'@).
+--
+-- @
+-- 'cis' = 'mkPolar' 1
+-- @
+--
+-- ==== __Examples__
+--
+-- >>> cis 0
+-- 1.0 :+ 0.0
+--
+-- The following examples are not perfectly zero due to [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754)
+--
+-- >>> cis pi
+-- (-1.0) :+ 1.2246467991473532e-16
+--
+-- >>> cis (4 * pi) - cis (2 * pi)
+-- 0.0 :+ (-2.4492935982947064e-16)
 {-# SPECIALISE cis :: Double -> Complex Double #-}
 cis              :: Floating a => a -> Complex a
 cis theta        =  cos theta :+ sin theta
 
 -- | The function 'polar' takes a complex number and
--- returns a (magnitude, phase) pair in canonical form:
--- the magnitude is non-negative, and the phase in the range @(-'pi', 'pi']@;
--- if the magnitude is zero, then so is the phase.
+-- returns a ('magnitude', 'phase') pair in canonical form:
+-- the 'magnitude' is non-negative, and the 'phase' in the range @(-'pi', 'pi']@;
+-- if the 'magnitude' is zero, then so is the 'phase'.
+--
+-- @'polar' z = ('magnitude' z, 'phase' z)@
+--
+-- ==== __Examples__
+--
+-- >>> polar (1.0 :+ 1.0)
+-- (1.4142135623730951,0.7853981633974483)
+--
+-- >>> polar ((-1.0) :+ 0.0)
+-- (1.0,3.141592653589793)
+--
+-- >>> polar (0.0 :+ 0.0)
+-- (0.0,0.0)
 {-# SPECIALISE polar :: Complex Double -> (Double,Double) #-}
 polar            :: (RealFloat a) => Complex a -> (a,a)
 polar z          =  (magnitude z, phase z)
 
--- | The non-negative magnitude of a complex number.
+-- | The non-negative 'magnitude' of a complex number.
+--
+-- ==== __Examples__
+--
+-- >>> magnitude (1.0 :+ 1.0)
+-- 1.4142135623730951
+--
+-- >>> magnitude (1.0 + 0.0)
+-- 1.0
+--
+-- >>> magnitude (0.0 :+ (-5.0))
+-- 5.0
 {-# SPECIALISE magnitude :: Complex Double -> Double #-}
 magnitude :: (RealFloat a) => Complex a -> a
 magnitude (x:+y) =  scaleFloat k
@@ -119,8 +218,16 @@
                           mk = - k
                           sqr z = z * z
 
--- | The phase of a complex number, in the range @(-'pi', 'pi']@.
--- If the magnitude is zero, then so is the phase.
+-- | The 'phase' of a complex number, in the range @(-'pi', 'pi']@.
+-- If the 'magnitude' is zero, then so is the 'phase'.
+--
+-- ==== __Examples__
+--
+-- >>> phase (0.5 :+ 0.5) / pi
+-- 0.25
+--
+-- >>> phase (0 :+ 4) / pi
+-- 0.5
 {-# SPECIALISE phase :: Complex Double -> Double #-}
 phase :: (RealFloat a) => Complex a -> a
 phase (0 :+ 0)   = 0            -- SLPJ July 97 from John Peterson
diff --git a/Data/Data.hs b/Data/Data.hs
--- a/Data/Data.hs
+++ b/Data/Data.hs
@@ -631,6 +631,8 @@
                         }
 
 -- | Constructs a constructor
+--
+-- @since 4.16.0.0
 mkConstrTag :: DataType -> String -> Int -> [String] -> Fixity -> Constr
 mkConstrTag dt str idx fields fix =
         Constr
diff --git a/GHC/Event/KQueue.hsc b/GHC/Event/KQueue.hsc
--- a/GHC/Event/KQueue.hsc
+++ b/GHC/Event/KQueue.hsc
@@ -44,8 +44,8 @@
 import GHC.Real (quotRem, fromIntegral)
 import GHC.Show (Show(show))
 import GHC.Event.Internal (Timeout(..))
-import System.Posix.Internals (c_close)
-import System.Posix.Types (Fd(..))
+import System.Posix.Internals (c_close,c_getpid)
+import System.Posix.Types (Fd(..), CPid)
 import qualified GHC.Event.Array as A
 
 #if defined(netbsd_HOST_OS)
@@ -73,19 +73,26 @@
 data KQueue = KQueue {
       kqueueFd     :: {-# UNPACK #-} !KQueueFd
     , kqueueEvents :: {-# UNPACK #-} !(A.Array Event)
+    , kqueuePid    :: {-# UNPACK #-} !CPid -- ^ pid, used to detect forks
     }
 
 new :: IO E.Backend
 new = do
   kqfd <- kqueue
   events <- A.new 64
-  let !be = E.backend poll modifyFd modifyFdOnce delete (KQueue kqfd events)
+  pid <- c_getpid
+  let !be = E.backend poll modifyFd modifyFdOnce delete (KQueue kqfd events pid)
   return be
 
 delete :: KQueue -> IO ()
 delete kq = do
-  _ <- c_close . fromKQueueFd . kqueueFd $ kq
-  return ()
+  -- detect forks: the queue isn't inherited by a child process created with
+  -- fork. Hence we mustn't try to close the old fd or we might close a random
+  -- one (e.g. the one used by timerfd, cf #24672).
+  pid <- c_getpid
+  when (pid == kqueuePid kq) $ do
+    _ <- c_close . fromKQueueFd . kqueueFd $ kq
+    return ()
 
 modifyFd :: KQueue -> Fd -> E.Event -> E.Event -> IO Bool
 modifyFd kq fd oevt nevt = do
diff --git a/base.cabal b/base.cabal
--- a/base.cabal
+++ b/base.cabal
@@ -1,19 +1,23 @@
 cabal-version:  3.0
 name:           base
-version:        4.19.1.0
+version:        4.19.2.0
 -- NOTE: Don't forget to update ./changelog.md
 
 license:        BSD-3-Clause
 license-file:   LICENSE
 maintainer:     Core Libraries Committee <core-libraries-committee@haskell.org>
 bug-reports:    https://github.com/haskell/core-libraries-committee/issues
-synopsis:       Basic libraries
+synopsis:       Core data structures and operations
 category:       Prelude
 build-type:     Configure
-description:
-    This package contains the Standard Haskell "Prelude" and its support libraries,
-    and a large collection of useful libraries ranging from data
-    structures to parsing combinators and debugging utilities.
+description:    Haskell's base library provides, among other things, core types (e.g. [Bool]("Data.Bool") and [Int]("Data.Int")),
+                data structures (e.g. [List]("Data.List"), [Tuple]("Data.Tuple") and [Maybe]("Data.Maybe")),
+                the [Exception]("Control.Exception") mechanism, and the [IO]("System.IO") & [Concurrency]("Control.Concurrent") operations.
+                The "Prelude" module, which is imported by default, exposes a curated set of types and functions from other modules.
+
+                Other data structures like [Map](https://hackage.haskell.org/package/containers/docs/Data-Map.html),
+                [Set](https://hackage.haskell.org/package/containers/docs/Data-Set.html) are available in the [containers](https://hackage.haskell.org/package/containers) library.
+                To work with textual data, use the [text](https://hackage.haskell.org/package/text/docs/Data-Text.html) library.
 
 extra-tmp-files:
     autom4te.cache
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,10 @@
 # Changelog for [`base` package](http://hackage.haskell.org/package/base)
 
+## 4.19.2.0 *October 2024*
+  * Shipped with GHC 9.8.3
+  * Improve documentation of various functions
+  * Fix interaction between `fork` and the `kqueue`-based IO manager ([#24672](https://gitlab.haskell.org/ghc/ghc/-/issues/24672))
+
 ## 4.19.1.0 *October 2023*
   * Shipped with GHC 9.8.2
   * Improve documentation of various functions
