1. 15

  2. 1

    This still assumes proper usage, i.e holding on to activeCert. I don’t see how it’s really any better than calling reference counting functions to decide when to remove the pointer from the map and let the GC collect it.

    1. 3

      I agree that the post is disappointing, because what it presents is an unsafe workaround to the absence of weak references. This being said, I think that it is a bit better than what you mention, because:

      • I think it is less invasive than having to add reference-count updates, because it naturally follows the data flow. If I’m responsible for a subsystem that carries a certificate in another structure with other things, I just need to make sure that I carry the cache-evictor as well and voilà, my entire subsystem is safe. Compare this to auditing all places where I get a certificate in input, and having to decide whether I have to put refcounting updates there and whether they are correct. (Does my borrowing of the certificate extend after the runtime of the function?)

      • In this particular case where we are only dealing about cache eviction, evicting too early is probably better than evicting too late. If you forget reference-increment instruction (or if you get rid of the finalized evictor, in the finalizer approach) you evict too early. But if you forget a reference-decrement instruction, you evict too late, and this gives you a cache leak. I suspect that it is harder to do the same mistake with the gc-based solution – this would correspond to leaking the finalized evictor, for example by storing it into a global variable.

      1. 2

        I wouldn’t call it unsafe – if you misuse the API, you won’t get a crash or a resource leak.

        1. 1

          We use weak references or ephemerons to guarantee that our code does not modify the liveness of objects and does not extend their lifetime. In this context by “correct” or “safe” I mean “preserving this guarantee”, and by “unsafe” I meant “the guarantee now depends on programmer discipline”. If you get this workaround wrong, you can have a resource leak where things stay alive longer than you expected. (But indeed, no segfault or something like that.) (In the present case, if I understand correctly, this is all internal to the Go stdlib implementation, so the set of people that need to be careful is restricted in a good way.)