Bug em locks leitor/escritor na API do Windows

Um bug de longa data nos locks slim reader/writer (SRW) do Windows foi descoberto por meio de `std::shared_mutex` do C++, permitindo que uma thread que pede um lock compartilhado às vezes obtenha acesso exclusivo e potencialmente cause deadlocks em certos padrões. Comentadores observam que esse comportamento provavelmente vem desde o Vista e decorre de escolhas sutis de implementação e trade-offs de justiça em primitivas de concorrência, com implementações alternativas no Wine e no ReactOS aparentemente sem esse problema. O incidente também destaca o quanto é difícil para desenvolvedores externos relatar bugs de baixo nível do Windows pelos canais oficiais, em contraste com ecossistemas mais abertos ou melhor mantidos, e leva muitos a evitar locks leitor/escritor a menos que o profiling prove que eles compensam a complexidade.

Bug no Windows SRWLOCK e impacto

  • O bug está no slim reader/writer (SRW) lock do Windows; std::shared_mutex no Windows é construído sobre SRW, então herda o problema.
  • Cenário: depois que um proprietário exclusivo libera o lock enquanto vários leitores estão tentando adquirir acesso compartilhado ao mesmo tempo, o lock pode entrar em deadlock.
  • Um engenheiro da Microsoft confirmou que foi aberto um bug interno no SO; há debate sobre se o comportamento é um bug de implementação ou um contrato mal especificado.
  • Explicação a partir de análise de baixo nível: uma sequência não atômica na liberação exclusiva permite que um adquirente compartilhado às vezes acabe com um lock exclusivo ou de outra forma “roube” o lock, deixando os espera não despertados.

Semântica e design de locks leitor/escritor

  • Vários comentaristas observam que locks RW são enganosamente complexos e propensos a bugs sutis; alguns os evitam a menos que o profiling prove um benefício.
  • O modo compartilhado é apresentado como uma otimização, não como uma garantia estrita de que todos os leitores possam sempre coexistir.
  • Justiça versus desempenho: locks SRW são intencionalmente injustos para evitar starvation de escritores e reduzir overhead de troca de contexto; isso pode bloquear leitores que chegam mais tarde mesmo quando leitores existentes estão ativos.
  • Padrões alternativos discutidos: double-buffering, locking mais granular, esquemas do tipo RCU, versionamento baseado em shared_ptr.

Corretude do programa de repro

  • Um comentarista afirma que o exemplo tem um data race em um contador de threads não atômico, sugerindo que isso sozinho poderia causar travamentos.
  • Outros rebatem: criação/junção de threads estabelece uma relação happens-before; em x86 e com std::thread esse padrão é considerado seguro, e tornar o contador constexpr ou atômico não elimina o bug.
  • O consenso no tópico tende para “o programa está correto; a implementação SRW é a culpada”.

Implementações e plataformas alternativas

  • RwLock e Mutex do Rust no Windows também usam SRW; Mutex é seguro porque usa apenas o modo exclusivo.
  • WINE e ReactOS usam designs baseados em CAS e aparentemente não exibem esse bug.
  • Algumas pessoas compartilham experiências construindo suas próprias variantes de SRW/pushlock, enfatizando a complexidade apesar das pequenas estruturas de dados.

Relato do bug e experiências com suporte

  • Relatar bugs da API do Windows é descrito como muito difícil; o Feedback Hub é visto como tendo pouco sinal.
  • Workarounds incluem: abrir “documentation bugs”, usar repositórios de issues no GitHub (para a STL) ou contatar engenheiros via redes sociais.
  • Comparações: o kernel Linux e algumas equipes da Apple são descritos como mais responsivos, enquanto grandes fornecedores frequentemente priorizam roadmaps e clientes pagantes.
  • Frustração mais ampla com sistemas corporativos de feedback: relatórios de baixa qualidade, scripts da primeira linha de suporte e trackers de bugs que parecem “gritar no vazio”.