Latest activity:

Implementing smart monitors in C++

Continuing our C++ programming tricks, we are gonna see a method for implementing smart monitors using C++ templates.

Probably you are thinking – what the hell is a smart monitor? Well, I haven’t found a better name. With “smart monitor” I mean a monitor which may be used to protected any object from concurrent access in multithreading programs. With “any object” I mean objects of any class, either written by you or implemented by third-parties. It sounds interesting, isn’t it?

Here we have a fragment of code typically problematic:

   class IntGenerator {
   public:
      virtual int generateValue() const = 0;
   };

   typedef std::set<int> IntSet;

   IntGenerator *igen = ...; // initializes a integer generator
   IntSet dataset;

   void *entrypoint(void *data) {
      while (true)
         dataset.insert(igen->generateValue());
   }

   int main() {
      pthread_t thr[2];
      pthread_create(&thr[0], NULL, entrypoint, NULL);
      pthread_create(&thr[1], NULL, entrypoint, NULL);
   }

The concurrent access to dataset probably derive in a inconsistent state in its internal binary tree.

The semantic we want to obtain is the following. We have a template class called Monitor, and we may use it in the following manner (only different code is shown).

   IntSet dataset;
   Monitor<IntSet> mdataset(&dataset);

   void *entrypoint(void *data) {
      while (true)
         mdataset->insert(igen->generateValue());
   }

The main difference is that we have created a new monitor object using dataset as input. Now we can use it with member by pointer operator to invoke the insert() operation. The result is that this invocation is thread-safe, i.e. there is no other thread accesing any member of dataset while insert() is invoked.

Where is the magic? Ok, obviously the monitor maintains a reference to the monitored object, used to invoke the insert() operation. The following code fragment is easily suspected.

template <class T>
class Monitor {
public:

  Monitor(T *obj) : mObj(obj) {}

private:

  T *mObj;
};

The presence of member by pointer operator reveals its overloading.

  T *operator -> () { ... }

What’s inside that operator? Ok, not so hasty. Since this operation provides a thread-safe semantic, the following code is not possible.

  T *operator -> () { return mObj;}

It’s obvious that the following also doesn’t work.

  T *operator -> () {
    somemutex.lock();
    return mObj;
    somemutex.unlock();
  }

It’s very clear that any prefix may be included before the monitored object is returned. But, we can’t include any suffix after the return statement. I swear that there is a solution which provides the semantic discussed above. Would you know which one?

Ejemplo de punteros inteligentes C++ en TIDorb

Al hilo del post de Alvaro, sobre punteros inteligentes, me gustaría presentar cómo los hemos implementado en el ORB TIDorb, incluyendo multithreading con POSIX threads. La especificación CORBA para C++ hace un uso intensivo de punteros inteligentes para manejar las referencias a objetos CORBA que suelen usarse por distintos threads concurrentemente.

Este trozo de código pertenece a la librería TIDThread que recubre la API de POSIX threads al estilo Java. Podeis ver el código completo aquí.

Read the rest of this entry »

Tags: none

Punteros ¿inteligentes? en C++

Uno de los mayores quebraderos de cabeza que provoca la programación en C/C++ es el uso de punteros. Un puntero mal gestionado puede provocar desde la típica violación de segmento hasta la corrupción de la memoria del programa (algo muy muy muy muy muy muy muy divertido de depurar).

Otros entornos como Java nos permiten olvidarnos de este infierno gracias a los recolectores de basura. En esta entrada, vamos a ver cómo construir un sencillo mecanismo que nos ofrece algo muy parecido, como viene siendo habitual, en C++.

Read the rest of this entry »

Sorry, but this post is not available in English

Read the rest of this entry »

Tipos covariantes en miembros virtuales

Después de mucho tiempo sin actividad, hoy vamos a hablar de uno de esos mecanismos que implementan los lenguajes modernos que nos hacen la vida más sencilla: el uso de tipos de retorno covariantes en las funciones miembro virtuales. Viendo el nombre, parece algo bastante complejo; pero no os asustéis. Es algo simple y, en ciertas ocasiones, muy útil.

Read the rest of this entry »