Contract weekly report #61

Blog post by PulkoMandy on Fri, 2015-01-30 09:27

Hello there!

As you may have noticed if you watch the commit list closely, my libbind work has not been merged yet. There are still some bugs to solve there, but I got sidetracked. I use BReferenceable in my DNS cache implementation to keep track of the cache entries. BReferenceable is a class used in Haiku to implement reference counted objects. In C++, the language only has very simple memory management, in the form of the new and delete operators. Objects can be allocated on the stack (they are temporary and only last as long as the function they are declared in is executing), or on the heap (for long lived objects). Objects allocated on the stack are deleted automatically when the function exits, while objects allocated on the heap must be deleted manually. This is one of the annoying parts of C++: managing the lifetime of these objects, making sure they are deleted only once, and that no one will try to use them after deletion.

In languages such as Java, object deletion is managed by a "garbage collector": this is a specific piece of code that looks for unused objects and releases their memory. It completely removes the need for the programmer to handle memory allocation and release. This solution has some limitations and is not easily applicable to C++ in a generic way.

Reference counting is a simpler approach to this. The idea is that each object knows how many "references" there are to it from other parts of the code. When the last reference is released, the object is unreachable and can be deleted. With the BReferenceable implementation, the C++ programmer must still manually acquire and release references to the object. This leaves more control of the memory allocation to him, while simplifying the memory management a lot.

BReferenceable can also be used to implement object pools, objects with shared or transferable ownership, and a few other patterns. As such it is a rather generic class, and used in many places throughout the system.

While trying to use BReferenceable in the DNS cache I got crashing issues with it and clearly invalid reference counts. I wanted to debug this, so I enabled the debugging features in BReferenceable. But this didn't work too well. I kept hitting issues in other places of the code using BReferenceable in ways that worked fine in release mode, but that the debug mode code didn't allow.

I fixed some of these in app_server so I could get a reasonably usable system, and continue debugging, but there are issues in several other places (for example in the package_daemon). This raised some discussion on whether the way BReferenceable is used in these places should actually be allowed, and to help resolve the issue, I wrote some documentation for the BReferenceable class.

I also worked on a way to handle references to const objects, which wasn't possible until now.

I also fixed a bug in the new getifaddrs implementation which locked the net_server on the first attempt to configure a network card. With that fixed I got DNS requests working, but very slowly. I will need to find why this happens.

I also did some work on WebKit again. As you probably know, there are problems with redirect requests, and sometimes Web+ would deadlock when loading a page. I found where the problem comes from, and partially fixed it, but there still are some issues. Either way, the situation is already much better, so I packaged a new WebKit release (1.4.9). I will try to fix the remaining issues in the coming weeks.

Comments

Re: Contract weekly report #61

Hi.
I didn't follow close the article, but I wonder why you don't mention the smartpointers of c++11/c++14 , you completely don't mention them, like they would not exist or be an alternative.

Re: Contract weekly report #61

Obviously we can't use C++11/14 smart pointers because of our reliance on gcc2 and backwards compatibility with BeOS R5... Maybe for R2 though.

Re: Contract weekly report #61

Actually we could implement the C++11 smart pointers. These are changes to the STL and don't need any compiler features. However, there isn't much motivation in upgrading our STL to C++11 standards.

std::shared_ptr can be used to implement reference counted objects, but it is more limited than BReferenceable, as it can't be used to implement reusable object pools. In BReferenceable this is done by not deleting the object when its reference count reaches 0, which shared_ptr does not allow. Also, BReferenceable has an inline reference count, I think smart_ptr has an out of line count (it is not stored inside the pointed object). But I'm not sure about that last statement, I didn't use C++11 smart pointers a lot lately.

Re: Contract weekly report #61

I think you are doing an excellent job.

Re: Contract weekly report #61

C++11 smart pointers can contain refcount in the object's memory block, if you use std::make_shared, to create such a pointer. It should allocate single block of memory, which could look like this:

{
  (mutex)
  refcount
  weekrefcount
  deleter {
    referenced object data
  }
}

If you don't use make_shared, it won't use the same memory block, it will look like this:
{
  (mutex)
  refcount
  weekrefcount
  deleter {
    pointer to referenced object -> { referenced object data }
  }
}

But shared_ptr contains 2 pointers, and is thus bigger than if it used just one - it is because it allows you to typecast the pointer and at the same time not forcing you to have virtual destructor. It looks something like this:

{
  pointer to referenced object
  pointer to shared_ptr refcount block
}

Whether to use shared_ptr or not, that is use-case question, I can't answer for you.