2009-05-19 10 views
12

Abbiamo un errore di lunga data nel nostro codice di produzione. Questo è essenzialmente un daemon basato su socket. Ascolta un gruppo di file scansionati usando select.Seleziona EBADF: quale FD è cattivo?

Occasionalmente (una volta al giorno circa), la selezione verrà restituita con EBADF.

Ho scritto codice per cercare l'archivista non valido, che scorre su ogni fd e chiama su di esso. Queste chiamate non restituiscono mai EBADF. Ho anche provato fstat. Inoltre non restituiscono mai EBADF.

Ho anche riscritto il daemon per utilizzare il poll. Questo non ha aiutato.

Qualcuno ha qualche altra idea? (a parte ho fatto un errore stupido, che è tutto facile da fare con select).

risposta

4

Sono d'accordo con James. Con poll(), hai revents per fd che puoi facilmente controllare.

I.e.

struct pollfd fds[NUM_FDS]; 
int ret, i; 

... 

ret = poll(fds, NUM_FDS, POLL_TIMEOUT); 
for (i = 0; i < NUM_FDS; i++) 
    if (fds[i].revents & POLLHUP || fds[i].revents & POLLNVAL) 
    ... do something ... 

Ovviamente non lo implementereste in questo modo nel mondo reale, è solo un esempio. Ho smesso di usare select() molto tempo fa, poll() è un'interfaccia molto migliore. Hai ragione, è semplicemente troppo facile spararti ai piedi con select().

4

Molto probabilmente lo select viene chiamato su un descrittore di file chiuso. La solita fonte è riutilizzare lo fd_set senza inizializzarlo di nuovo. Avete qualcosa in corso nei gestori di segnale? (come riaprire un file di registro su un HUP?)

3

Se si utilizza il poll(), è possibile esaminare i dati e individuare il guasto di fd, il che rappresenta il grande vantaggio.