Error en los locks lector/escritor de la API de Windows

Un bug de larga data en los slim reader/writer (SRW) locks de Windows ha sido descubierto a través de `std::shared_mutex` de C++, permitiendo que un hilo que pide un lock compartido a veces obtenga acceso exclusivo y potencialmente cause deadlocks en ciertos patrones. Los comentaristas señalan que este comportamiento probablemente se remonta a Vista y proviene de decisiones sutiles de implementación y compromisos de justicia en primitivas de concurrencia, con implementaciones alternativas en Wine y ReactOS que parecen no verse afectadas. El incidente también pone de relieve lo difícil que es para desarrolladores externos reportar bugs de bajo nivel de Windows a través de los canales oficiales, en contraste con ecosistemas más abiertos o mejor mantenidos, y lleva a muchos a evitar los locks lector-escritor salvo que el perfilado demuestre que valen la pena por su complejidad.

Error de Windows SRWLOCK y su impacto

  • El error está en el slim reader/writer (SRW) lock de Windows; std::shared_mutex en Windows se basa en SRW, así que hereda el problema.
  • Escenario: después de que un propietario exclusivo libera el lock mientras varios lectores intentan adquirir acceso compartido al mismo tiempo, el lock puede entrar en deadlock.
  • Un ingeniero de Microsoft confirmó que se registró un bug interno del sistema operativo; hay debate sobre si el comportamiento es un bug de implementación o un contrato mal especificado.
  • Explicación a partir de análisis de bajo nivel: una secuencia no atómica en la liberación exclusiva permite que un adquiriente compartido a veces termine con un lock exclusivo o “robe” el lock, dejando a los que esperan sin ser despertados.

Semántica y diseño de los locks lector/escritor

  • Varios comentaristas señalan que los RW locks son engañosamente complejos y propensos a errores sutiles; algunos los evitan salvo que el perfilado demuestre una ventaja.
  • El modo compartido se presenta como una optimización, no como una garantía estricta de que todos los lectores puedan coexistir siempre.
  • Justicia frente a rendimiento: los SRW locks están diseñados para ser injustos intencionadamente para evitar la inanición de escritores y reducir la sobrecarga de cambios de contexto; esto puede bloquear a lectores que llegan tarde incluso cuando ya hay lectores activos.
  • Se discutieron patrones alternativos: double-buffering, locking de granularidad más fina, esquemas tipo RCU, versionado basado en shared_ptr.

Corrección del programa de repro

  • Un comentarista afirma que el ejemplo tiene una data race sobre un conteo de hilos no atómico, sugiriendo que eso por sí solo podría causar cuelgues.
  • Otros refutan: la creación/unión de hilos establece una relación happens-before; en x86 y con std::thread este patrón se considera seguro, y hacer el conteo constexpr o atómico no elimina el bug.
  • El consenso en el hilo se inclina hacia “el programa está bien; la implementación de SRW tiene la culpa”.

Implementaciones y plataformas alternativas

  • Los RwLock y Mutex de Rust en Windows también usan SRW; Mutex es seguro porque solo usa el modo exclusivo.
  • WINE y ReactOS usan diseños basados en CAS y parece que no presentan este bug.
  • Algunos comparten experiencias construyendo sus propias variantes de SRW/pushlock, destacando la complejidad pese al pequeño tamaño de las estructuras de datos.

Informes de bugs y experiencias de soporte

  • Reportar bugs de la API de Windows se describe como muy difícil; Feedback Hub se considera de baja señal.
  • Entre las soluciones alternativas están: enviar “documentation bugs”, usar trackers de issues en GitHub (para STL) o contactar a ingenieros por redes sociales.
  • Comparaciones: el kernel de Linux y algunos equipos de Apple se describen como más receptivos, mientras que los grandes proveedores suelen priorizar hojas de ruta y clientes de pago.
  • Frustración más amplia con los sistemas corporativos de feedback: informes de baja calidad, guiones de soporte de primera línea y trackers de bugs donde es como “gritar al vacío”.