2017-10-12 3 views
6

j'ai donc une cow_ptr simple. Il ressemble à ceci:copie à l'écriture avec shared_ptr

template<class T, class Base=std::shared_ptr<T const>> 
struct cow_ptr:private Base{ 
    using Base::operator*; 
    using Base::operator->; 
    using Base::operator bool; 
    // etc 

    cow_ptr(std::shared_ptr<T> ptr):Base(ptr){} 

    // defaulted special member functions 

    template<class F> 
    decltype(auto) write(F&& f){ 
    if (!unique()) self_clone(); 
    Assert(unique()); 
    return std::forward<F>(f)(const_cast<T&>(**this)); 
    } 
private: 
    void self_clone(){ 
    if (!*this) return; 
    *this = std::make_shared<T>(**this); 
    Assert(unique()); 
    } 
}; 

ce qui garantit qu'il est titulaire d'un non-const T et assure qu'il est unique quand il .write([&](T&){}) s à elle.

La désapprobation de .unique() semble indiquer que cette conception est erronée.

Je suppose que si nous commençons par un cow_ptr<int> ptr avec 1 en fil A, passer à fil B, le rendre unique, le modifier à 2, passer ptr en arrière et lire en fil A nous avons généré une course condition.

Comment résoudre ce problème? Puis-je simplement ajouter une barrière de mémoire dans write? Laquelle? Ou le problème est-il plus fondamental?

sont des symptômes moins probable sur x86 en raison de la cohérence de la mémoire x86 allant au-delà de ce que demande C++?

Répondre

0

Je pense que l'idée de désapprouver est qu'il ne peut pas être utilisé de manière incorrecte comme si vous aviez le code comme ceci:

if(sp.unique()) { 
    // some deinitialisation 
} else { 
    // somebody else will deinitialise. 
} 

Il est possible qu'il échouera à deinitialise si elle arrive à courir 2 fois simultanément.

Dans votre cas particulier, je ne vois aucun problème, parce que

  1. si elle n'a pas été unique et est devenu unique - il n'y a pas grand-chose, il vous suffit de faire une copie supplémentaire
  2. si elle était unique et deveniez pas unique, alors vous changer et copier la même instance dans deux threads différents (ce qui sera un problème de toute façon)

Je ne pense pas qu'il y ait une autre question avec l'ordre d'accès à la mémoire depuis les compteurs en shared_ptr sont atomique.

Je voudrais probablement passer à use_count == 1 peut être avec le commentaire approprié