compat_libevent.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* Copyright (c) 2009, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file compat_libevent.c
  5. * \brief Wrappers to handle porting between different versions of libevent.
  6. *
  7. * In an ideal world, we'd just use Libevent 2.0 from now on. But as of June
  8. * 2009, Libevent 2.0 is still in alpha, and we will have old versions of
  9. * Libevent for the forseeable future.
  10. **/
  11. #include "orconfig.h"
  12. #include "compat_libevent.h"
  13. #include "compat.h"
  14. #include "util.h"
  15. #include "log.h"
  16. #ifdef HAVE_EVENT2_EVENT_H
  17. #include <event2/event.h>
  18. #else
  19. #include <event.h>
  20. #endif
  21. #ifdef HAVE_EVENT_SET_LOG_CALLBACK
  22. /** A string which, if it appears in a libevent log, should be ignored. */
  23. static const char *suppress_msg = NULL;
  24. /** Callback function passed to event_set_log() so we can intercept
  25. * log messages from libevent. */
  26. static void
  27. libevent_logging_callback(int severity, const char *msg)
  28. {
  29. char buf[1024];
  30. size_t n;
  31. if (suppress_msg && strstr(msg, suppress_msg))
  32. return;
  33. n = strlcpy(buf, msg, sizeof(buf));
  34. if (n && n < sizeof(buf) && buf[n-1] == '\n') {
  35. buf[n-1] = '\0';
  36. }
  37. switch (severity) {
  38. case _EVENT_LOG_DEBUG:
  39. log(LOG_DEBUG, LD_NET, "Message from libevent: %s", buf);
  40. break;
  41. case _EVENT_LOG_MSG:
  42. log(LOG_INFO, LD_NET, "Message from libevent: %s", buf);
  43. break;
  44. case _EVENT_LOG_WARN:
  45. log(LOG_WARN, LD_GENERAL, "Warning from libevent: %s", buf);
  46. break;
  47. case _EVENT_LOG_ERR:
  48. log(LOG_ERR, LD_GENERAL, "Error from libevent: %s", buf);
  49. break;
  50. default:
  51. log(LOG_WARN, LD_GENERAL, "Message [%d] from libevent: %s",
  52. severity, buf);
  53. break;
  54. }
  55. }
  56. /** Set hook to intercept log messages from libevent. */
  57. void
  58. configure_libevent_logging(void)
  59. {
  60. event_set_log_callback(libevent_logging_callback);
  61. }
  62. /** Ignore any libevent log message that contains <b>msg</b>. */
  63. void
  64. suppress_libevent_log_msg(const char *msg)
  65. {
  66. suppress_msg = msg;
  67. }
  68. #else
  69. void
  70. configure_libevent_logging(void)
  71. {
  72. }
  73. void
  74. suppress_libevent_log_msg(const char *msg)
  75. {
  76. (void)msg;
  77. }
  78. #endif
  79. #ifndef HAVE_EVENT2_EVENT_H
  80. /** Work-alike replacement for event_new() on pre-Libevent-2.0 systems. */
  81. struct event *
  82. tor_event_new(struct event_base *base, int sock, short what,
  83. void (*cb)(int, short, void *), void *arg)
  84. {
  85. struct event *e = tor_malloc_zero(sizeof(struct event));
  86. event_set(e, sock, what, cb, arg);
  87. event_base_set(base, e);
  88. return e;
  89. }
  90. /** Work-alike replacement for evtimer_new() on pre-Libevent-2.0 systems. */
  91. struct event *
  92. tor_evtimer_new(struct event_base *base,
  93. void (*cb)(int, short, void *), void *arg)
  94. {
  95. return tor_event_new(base, -1, 0, cb, arg);
  96. }
  97. /** Work-alike replacement for evsignal_new() on pre-Libevent-2.0 systems. */
  98. struct event *
  99. tor_evsignal_new(struct event_base * base, int sig,
  100. void (*cb)(int, short, void *), void *arg)
  101. {
  102. return tor_event_new(base, sig, EV_SIGNAL, cb, arg);
  103. }
  104. /** Work-alike replacement for event_free() on pre-Libevent-2.0 systems. */
  105. void
  106. tor_event_free(struct event *ev)
  107. {
  108. event_del(ev);
  109. tor_free(ev);
  110. }
  111. #endif
  112. /** Global event base for use by the main thread. */
  113. struct event_base *the_event_base = NULL;
  114. /** Initialize the Libevent library and set up the event base. */
  115. void
  116. tor_libevent_initialize(void)
  117. {
  118. tor_assert(the_event_base == NULL);
  119. #ifdef HAVE_EVENT2_EVENT_H
  120. the_event_base = event_base_new();
  121. #else
  122. the_event_base = event_init();
  123. #endif
  124. }
  125. /** Return the current Libevent event base that we're set up to use. */
  126. struct event_base *
  127. tor_libevent_get_base(void)
  128. {
  129. return the_event_base;
  130. }
  131. /** Return the name of the Libevent backend we're using. */
  132. const char *
  133. tor_libevent_get_method(void)
  134. {
  135. #ifdef HAVE_EVENT2_EVENT_H
  136. return event_base_get_method(the_event_base);
  137. #elif defined(HAVE_EVENT_GET_METHOD)
  138. return event_get_method();
  139. #else
  140. return "<unknown>";
  141. #endif
  142. }