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_mutexen 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::threadeste patrón se considera seguro, y hacer el conteoconstexpro 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
RwLockyMutexde Rust en Windows también usan SRW;Mutexes 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”.