#include "svec.h"
#include "util.h"
#include "valgrind.h"
+#include "fatal-signal.h"
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(dpif)
};
static struct shash dpif_classes = SHASH_INITIALIZER(&dpif_classes);
+
/* Rate limit for individual messages going to or from the datapath, output at
* DBG level. This is very high because, if these are enabled, it is because
* we really need to see them. */
if (status < 0) {
int i;
+#ifdef THREADED
+ struct shash_node *node;
+#endif
status = 0;
for (i = 0; i < ARRAY_SIZE(base_dpif_classes); i++) {
dp_register_provider(base_dpif_classes[i]);
}
+
+#ifdef THREADED
+ /* register an exit handler for the registered classes */
+ SHASH_FOR_EACH(node, &dpif_classes) {
+ const struct registered_dpif_class *registered_class = node->data;
+ if (registered_class->dpif_class.exit_hook) {
+ fatal_signal_add_hook(registered_class->dpif_class.exit_hook,
+ NULL, NULL, true);
+ }
+ }
+#endif
}
}
+
+
/* Performs periodic work needed by all the various kinds of dpifs.
*
* If your program opens any dpifs, it must call both this function and
}
}
+#ifdef THREADED
+/* Start the datapath management.
+ *
+ * This function has been thought for a scenario in which the management of the
+ * datapath module and the ofproto module are performed in separate
+ * threads/processes module. */
+void
+dp_start(void)
+{
+ struct shash_node *node;
+
+ SHASH_FOR_EACH(node, &dpif_classes) {
+ const struct registered_dpif_class *registered_class = node->data;
+ if (registered_class->dpif_class.start) {
+ registered_class->dpif_class.start();
+ }
+ }
+}
+#endif
+
+
/* Registers a new datapath provider. After successful registration, new
* datapaths of that type can be opened using dpif_open(). */
int
dp_register_provider(const struct dpif_class *new_class)
{
struct registered_dpif_class *registered_class;
-
+
if (shash_find(&dpif_classes, new_class->type)) {
VLOG_WARN("attempted to register duplicate datapath provider: %s",
new_class->type);