2013-08-29 8 views
9

Sto usando Apache parser in C++ su Windows e vorrei chiedere il vostro aiuto con la cancellazione di un'operazione di lettura di blocco in corso. L'operazione di lettura (ad esempio - TProtocol :: readByte) viene bloccata finché non vengono ricevuti i dati. Quando chiudo il trasporto da un altro thread, ottengo un'asserzione fallita su un puntatore nullo.Annullamento di un'operazione di lettura blocco in Thrift

Esiste un altro modo per annullare un'operazione di lettura bloccata?

risposta

3

se si utilizza la modalità di blocco, quindi l'unica opzione per interrompere l'operazione di lettura è impostare un timeout sul TSocket prima di leggerlo.

+0

In questo caso, qualsiasi implementazione di TProtocol non sarà in grado di distinguere tra "il server non ha ancora inviato dati" e "l'utente desidera annullare l'operazione". Dato che non operiamo su una connessione veloce, abbiamo davvero bisogno di distinguere tra questi due casi. – Alex

+0

Perché ti interessa TProtocol? Ci sarà un lancio TimeoutException per entrambi i casi dopo la chiamata RPC, e tu potrai decidere cosa fare dopo. – secmask

+0

Poiché l'utente del nostro codice di comunicazione otterrà questa eccezione nel caso * legittimo * in cui la risposta del server non è ancora arrivata. Se il mio timeout è troppo lungo, la risposta della cancellazione sarà troppo lenta per il nostro cliente. Poiché operiamo in un ambiente con bassa larghezza di banda e latenza elevata, non possiamo permetterci brevi timeout, poiché quasi sempre accadranno. Tuttavia, vogliamo ancora annullare. – Alex

5

Supponendo di essere in esecuzione su Windows (in base ai tag della domanda): È possibile annullare un'operazione di blocco con socket con WSACancelBlockingCall (sebbene questa operazione sia deprecata, dovrebbe comunque funzionare). Il socket restituirà quindi il codice di errore WSAEINTR (Interrupted function call) anziché WSAETIMEDOUT.

In parsimonia, è possibile utilizzare TSocket::getSocketFD() o TPipe::getPipeHandle() per ottenere l'handle corrispondente per annullare l'operazione corrente.

+0

Sfortunatamente, WSACancelBlockingCall è stato rimosso da Winsock2. And Thrift utilizza Winsock2 (http://msdn.microsoft.com/en-us/library/windows/desktop/ms741547%28v=vs.85%29.aspx). Ma è una bella idea. – Alex

+0

È possibile utilizzare la funzione, è ancora presente in Winsock2 (sebbene non venga esportata dalla DLL). Se non vuoi usare un simile trucco, puoi anche chiudere il socket da un altro thread. L'operazione di blocco riceverà l'errore WSA_OPERATION_ABORTED (funziona per le operazioni di Winsock2, ma NON per le operazioni di Winsock1). –

Problemi correlati