/**
 * @file mvgal_fork.h
 * @brief Fork-safety and Wine/Proton compatibility for MVGAL
 *
 * Multi-Vendor GPU Aggregation Layer for Linux
 *
 * After fork(), only the calling thread survives in the child.
 * Any mutex locked by another thread at the moment of fork is
 * deadlocked forever in the child.  MVGAL uses pthread_atfork
 * to protect all registered mutexes.
 *
 * After a fork the child MUST NOT use any MVGAL function until
 * it calls mvgal_init() again.
 */

#ifndef MVGAL_FORK_H
#define MVGAL_FORK_H

#include <stdbool.h>
#include <pthread.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ------------------------------------------------------------------ */
/*  Constants                                                         */
/* ------------------------------------------------------------------ */

#define MVGAL_FORK_MAX_LOCKS  32   /**< max registered mutexes        */

/* ------------------------------------------------------------------ */
/*  Fork-safety — mutex registry                                      */
/* ------------------------------------------------------------------ */

/**
 * Register a mutex for pthread_atfork protection.
 * Called during subsystem init (mvgal_init, transport_init, etc.).
 *
 * @param lock  pointer to a pthread_mutex_t
 * @return 0 on success, -1 if registry is full
 */
int mvgal_fork_register(pthread_mutex_t *lock);

/**
 * Unregister a previously registered mutex.
 * Called during subsystem shutdown.
 *
 * @param lock  pointer that was passed to mvgal_fork_register
 * @return 0 on success, -1 if not found
 */
int mvgal_fork_unregister(pthread_mutex_t *lock);

/**
 * Set up the pthread_atfork(3) triplet.
 * Called once from mvgal_init().  Idempotent.
 *
 * @return 0 on success, -1 if atfork fails
 */
int mvgal_fork_init(void);

/**
 * Tear down fork-safety state.
 * Called from mvgal_shutdown().
 */
void mvgal_fork_shutdown(void);

/**
 * Reset all registered mutexes in a child process after fork.
 * The child is single-threaded so re-initialisation is safe.
 */
void mvgal_fork_reset(void);

/* ------------------------------------------------------------------ */
/*  Fork detection                                                    */
/* ------------------------------------------------------------------ */

/**
 * @return true if the current process is a child after fork()
 */
bool mvgal_was_forked(void);

/**
 * Clear the forked-child flag (called after successful re-init).
 */
void mvgal_clear_forked(void);

/* ------------------------------------------------------------------ */
/*  Wine / Proton detection                                           */
/* ------------------------------------------------------------------ */

/**
 * @return true if running under Wine (WINEPREFIX or wineserver set)
 */
bool mvgal_running_under_wine(void);

/**
 * @return true if running under Proton (STEAM_COMPAT_DATA_PATH etc.)
 */
bool mvgal_running_under_proton(void);

#ifdef __cplusplus
}
#endif

#endif /* MVGAL_FORK_H */
