Conexões e bloqueio de estrutura de arquivo
Para fins de bloqueio, há dois níveis de tabelas de pesquisa usadas:
Uma tabela de objetos por dispositivo para estruturas SRV_CALL e NET_ROOT (tabela de prefixo)
Uma estrutura de tabela por NET_ROOT para estruturas FCB (tabela FCB)
Essas tabelas separadas permitem que as operações de diretório em diferentes estruturas de NET_ROOT sejam quase completamente não interferindo depois que as conexões são estabelecidas. No entanto, as operações de diretório na mesma estrutura NET_ROOT interferem ligeiramente. A tabela a seguir descreve quais bloqueios são necessários para operações específicas:
Operação | Tipos de dados | Bloqueio necessário |
---|---|---|
Criar ou finalizar |
SRV_CALL NET_ROOT V_NET_ROOT | Um bloqueio exclusivo na tabela NetName (o campo TableLock de RxContext-RxDeviceObject-pRxNetNameTable>>). |
Referência, desreferência ou pesquisa |
SRV_CALL NET_ROOT V_NET_ROOT | Um bloqueio compartilhado ou exclusivo na tabela NetName (o campo TableLock de RxContext-RxDeviceObject-pRxNetNameTable>>). |
Criar ou finalizar |
FCB SRV_OPEN FOBX | Um bloqueio exclusivo na tabela FCB (o campo TableLock de NET_ROOT-FcbTable>). |
Referência, desreferência ou pesquisa |
FCB SRV_OPEN FOBX | Um bloqueio compartilhado ou exclusivo na tabela FCB (o campo TableLock de NET_ROOT-FcbTable>). |
Observe que as manipulações de estruturas de dados SRV_OPEN e FOBX atualmente exigem o mesmo bloqueio necessário para manipulações de estruturas de dados FCB. Isso é simplesmente uma ideia de economia de memória. Versões futuras do Windows podem adicionar outro recurso no nível fcb para remover essa restrição para que um conjunto de recursos compartilhados possa ser usado para diminuir a probabilidade de uma colisão para um nível aceitavelmente baixo.
Se você precisar de ambos os bloqueios (FinalizeNetFcb, por exemplo), deverá usar o bloqueio na tabela NetName primeiro e, em seguida, o bloqueio na tabela FCB. Você deve liberar os bloqueios na ordem oposta.
O processo de criação e finalização SRV_CALL, NET_ROOT e V_NET_ROOT é regido pela aquisição e liberação do bloqueio RDBSS na tabela NetName.
O processo de criação e finalização da FCB é regido pela aquisição e liberação do bloqueio na tabela NetName associada à estrutura NET_ROOT.
O processo de criação e finalização de FOBX e SRVOPEN é regido pela aquisição e liberação do bloqueio na tabela FCB.
A tabela a seguir resume os bloqueios e os modos nos quais os bloqueios precisam ser adquiridos para criação e finalização das várias estruturas de dados:
Tipo de operação | SRV_CALL | NET_ROOT | FCB | SRV_OPEN | FOBX |
---|---|---|---|---|---|
Criar |
Bloqueio exclusivo na tabela NetName |
Bloqueio exclusivo na tabela NetName |
Bloqueio exclusivo na tabela FCB |
Bloqueio exclusivo na tabela FCB |
Bloqueio exclusivo na tabela FCB |
Finalizar |
Bloqueio exclusivo na tabela NetName |
Bloqueio exclusivo na tabela NetName |
Bloqueio exclusivo na tabela FCB |
Bloqueio exclusivo na tabela FCB |
Bloqueio exclusivo na tabela FCB |
Referenciar e desreferenciar essas estruturas de dados também deve aderir a determinadas convenções.
Quando a contagem de referência associada a qualquer uma das estruturas de dados cai para 1 (a única referência que está sendo mantida pela tabela de nomes na maioria dos casos), a estrutura de dados é uma potencial candidata à finalização. A estrutura de dados pode ser finalizada imediatamente ou pode ser marcada para limpeza. Ambos os métodos são implementados no RDBSS. Quando os requisitos de bloqueio são atendidos durante a desreferenciamento, as estruturas de dados são finalizadas imediatamente. A única exceção a isso é quando a otimização de operação atrasada é implementada (desreferenciando a estrutura FCB, por exemplo). Caso contrário, a estrutura de dados será marcada para limpeza.
Um minidiretório de rede deve ter um bloqueio exclusivo na tabela NetName para chamar uma rotina de finalização.
Para executar um Create em uma dessas estruturas de dados, um driver de minidiretório de rede deve fazer algo semelhante ao seguinte:
getshared();lookup();
if (failed) {
release(); getexclusive(); lookup();
if ((failed) { create(); }
}
deref();
release();
Quando você tiver adquirido o bloqueio com êxito, insira o nó na tabela, libere o bloqueio e, em seguida, veja se o servidor está disponível. Se o servidor estiver disponível, configure o restante das informações e desbloqueie qualquer pessoa que esteja aguardando no mesmo servidor (as estruturas SRV_CALL ou NET_ROOT).