2011-12-18 16 views
5

I C++ 11 norma definisce unique_lock::unlock come (§ 30.4.2.2.2, p 1159.)È unique_lock :: unlock sotto specificato nello standard C++ 11?

void unlock(); 
Effects: pm->unlock() 
Postcondition: owns == false 
Throws: system_error when an exception is required (30.2.2). 
Error conditions: 
    — operation_not_permitted — if on entry owns is false. 

Tutte le altre operazioni di bloccaggio specificano che viene generata un'eccezione in almeno due occasioni:

  • il mutex è NULL (getta system_error con errc::operation_not_permitted)
  • il mutex è già bloccato (tiri system_error con errc::operation_not_permitted)

Il problema con mutex non valido è ovviamente possibile anche per unlock, tuttavia lo standard specifica il comportamento del programma solo per i problemi di blocco. È un vero errore nello standard o mi manca qualcosa?

+0

Non sono sicuro di seguirlo. Perché è "ovviamente possibile" che "unlock" venga chiamato quando il mutex non è valido? Si può dedurre che l'effetto di 'unlock()' è 'pm-> unlock()', che per evitare un comportamento indefinito 'pm' non deve essere nullo e il contratto per' BasicLockable' '* pm' deve essere soddisfatto , quindi il blocco deve essere di proprietà dell'agente di esecuzione corrente. C'è qualche sottigliezza che mi manca? –

risposta

7

Anche se non esplicitamente dichiarato, unique_lock ha le seguenti invarianti:

if pm == nullptr then owns == false 
if owns == true then pm != nullptr 

Non c'è proprio nessun modo per ottenere lo unique_lock in uno stato che viola questi invarianti tranne che per comportamento non definito. Quindi la clausola:

— operation_not_permitted — if on entry owns is false. 

copre il caso che pm == nullptr.

Si noti che ~unique_lock() chiama solo pm->unlock() se owns è vero. Se owns è vero, allora pm != nullptr e quindi unlock() non può essere lanciato.

0

pm è il mutex_type e la definizione per sbloccare in std::mutex è:

void unlock() noexcept; 

Cioè, la funzione unlock non può gettare alcuna eccezione, quindi unique_lock::unlock non dispone di ereditare una di queste eccezioni. Il motivo per cui è possibile lanciare qualsiasi eccezione è un mistero.

È un po 'fastidioso che il distruttore per unique_lock possa generare un'eccezione (poiché suppongo che potrebbe dover chiamare unlock dove può anche). Questo mi sembra un problema, dal momento che l'utilizzo di un oggetto di blocco per sbloccare correttamente durante la gestione delle eccezioni è un linguaggio molto comune. È davvero brutto che il lock possa lanciare un'eccezione durante lo srotolamento dello stack, specialmente perché non è consentito al mutex sottostante.

Qui c'è sicuramente qualcosa di sbagliato.

sto ancora lavorando dall'ultimo progetto pubblico, forse questo è stato fissato

+0

Sto guardando l'attuale standard C++ 11. Né 'unique_ptr :: ~ unique_ptr' è' noexcept', né è stata implementata la proposta di aggiungere implicitamente noex per i distruttori, quindi non è stata corretta.Tuttavia, penso che questo sia un problema diverso. Lo standard non specifica cosa succede nel caso in cui 'unique_ptr' non abbia mutex associato e' unlock' sia chiamato su quel lock. –

Problemi correlati