1
\$\begingroup\$

If many threads Borrow() and Return() an instance of Packet from/to PacketPool could the Exception in Packet.Init() ever be thrown? Assuming only PacketPool ever called the Init() and UnInit() methods on a Packet.

class PacketPool
{
    private Stack<Packet> pool;

    public PacketPool(int initalNum)
    {
        pool = new Stack<Packet>(initalNum);

        for (int i = 0; i < initalNum; i++)
        {
            Packet p = new Packet();
            pool.Push(p);
        }
    }

    public Packet Borrow()
    {
        Packet p;

        lock (pool)
        {
            if (pool.Count == 0)
            {
                p = new Packet();
            }
            else
            {
                p = pool.Pop();
            }
        }

        p.Init();

        return p;
    }

    public void Return(Packet p)
    {
        p.UnInit();

        lock (pool)
        {
            pool.Push(p);
        }
    }
}

class Packet
{
    bool isInitialized;

    public void Init()
    {
        if(isInitialized)
            throw new InvalidOperationException("Already initialized!");
        isInitialized = true;
    }

    public void UnInit()
    {
        isInitialized = false;
    }
}
\$\endgroup\$
2
\$\begingroup\$

Assuming only PacketPool ever called the Init() and UnInit() methods on a Packet.

I think that's not an assumption you should make. If the user of your code shouldn't call some methods, then don't let him do it, don't just assume that he won't.

What you could do is to return a facade to Packet that doesn't contain the two methods, instead of returning Packet directly.

\$\endgroup\$
  • \$\begingroup\$ Good point, currently I do have it in it's own namespace and could make the methods internal, though I will still have to be careful! \$\endgroup\$ – markmnl Aug 11 '13 at 12:54
  • \$\begingroup\$ @MarkMennell Having the methods internal in their own namespace won't stop a user calling them as classes within the assembly will still have access. My understanding is that those modifiers only work across assemblies themselves. Correct me if I'm wrong there though... \$\endgroup\$ – dreza Aug 11 '13 at 21:53
  • \$\begingroup\$ The modifiers work across namespace - so even in the same assembly if you are not in the namespace you cannot access something marked internal. Anyway the namespace is in it's own assembly, a dll, so a user cannot alter the source code in there either. \$\endgroup\$ – markmnl Aug 12 '13 at 0:26
  • 1
    \$\begingroup\$ @MarkMennell I think we must be thinking of something different. Going from this msdn.microsoft.com/en-us/library/ms173121.aspx internal means any class in the assembly (regardless of namespace can see it). Anyway, all to their own. \$\endgroup\$ – dreza Aug 12 '13 at 6:27
  • 1
    \$\begingroup\$ You are right, my bad! \$\endgroup\$ – markmnl Aug 12 '13 at 9:31
0
\$\begingroup\$

No, the exception in Packet.Init() will never be thrown. This is because although there may be multiple threads in Borrow(), the lock statement will ensure that each thread sees its own version of p.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.