LCOV - code coverage report
Current view: top level - lib/tevent - tevent_fd.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 73 89 82.0 %
Date: 2024-04-21 15:09:00 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    common events code for fd events
       5             : 
       6             :    Copyright (C) Stefan Metzmacher 2009
       7             : 
       8             :      ** NOTE! The following LGPL license applies to the tevent
       9             :      ** library. This does NOT imply that all of Samba is released
      10             :      ** under the LGPL
      11             : 
      12             :    This library is free software; you can redistribute it and/or
      13             :    modify it under the terms of the GNU Lesser General Public
      14             :    License as published by the Free Software Foundation; either
      15             :    version 3 of the License, or (at your option) any later version.
      16             : 
      17             :    This library is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      20             :    Lesser General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU Lesser General Public
      23             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : #include "replace.h"
      27             : #define TEVENT_DEPRECATED 1
      28             : #include "tevent.h"
      29             : #include "tevent_internal.h"
      30             : #include "tevent_util.h"
      31             : 
      32             : _PRIVATE_
      33        5174 : const char *tevent_common_fd_str(struct tevent_common_fd_buf *buf,
      34             :                                  const char *description,
      35             :                                  const struct tevent_fd *fde)
      36             : {
      37       15520 :         snprintf(buf->buf, sizeof(buf->buf),
      38             :                  "%s[fde=%p,"
      39             :                  "fd=%d,flags=0x%x(%s%s%s),%s]",
      40        5174 :                  description, fde, fde->fd,
      41        5172 :                  fde->flags,
      42        5172 :                  (fde->flags & TEVENT_FD_ERROR) ? "E" : "",
      43        5172 :                  (fde->flags & TEVENT_FD_READ) ? "R" : "",
      44        5174 :                  (fde->flags & TEVENT_FD_WRITE) ? "W" : "",
      45        5174 :                  fde->handler_name);
      46        5174 :         return buf->buf;
      47             : }
      48             : 
      49    24837984 : int tevent_common_fd_destructor(struct tevent_fd *fde)
      50             : {
      51    24837984 :         struct tevent_fd *primary = NULL;
      52             : 
      53    24837984 :         if (fde->destroyed) {
      54     8796138 :                 tevent_common_check_double_free(fde, "tevent_fd double free");
      55     8796138 :                 goto done;
      56             :         }
      57    16041846 :         fde->destroyed = true;
      58             : 
      59             :         /*
      60             :          * The caller should have cleared it from any mpx relationship
      61             :          */
      62    16041846 :         primary = tevent_common_fd_mpx_primary(fde);
      63    16041846 :         if (primary != fde) {
      64           0 :                 tevent_abort(fde->event_ctx,
      65             :                         "tevent_common_fd_destructor: fde not mpx primary");
      66    16041846 :         } else if (fde->mpx.list != NULL) {
      67           0 :                 tevent_abort(fde->event_ctx,
      68             :                         "tevent_common_fd_destructor: fde has mpx fdes");
      69             :         }
      70             : 
      71    16041846 :         if (fde->event_ctx) {
      72    15003918 :                 tevent_trace_fd_callback(fde->event_ctx, fde, TEVENT_EVENT_TRACE_DETACH);
      73    15003918 :                 DLIST_REMOVE(fde->event_ctx->fd_events, fde);
      74             :         }
      75             : 
      76    16041846 :         if (fde->close_fn) {
      77    10179025 :                 fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data);
      78    10179025 :                 fde->fd = -1;
      79    10179025 :                 fde->close_fn = NULL;
      80             :         }
      81             : 
      82    16041846 :         fde->event_ctx = NULL;
      83    24837984 : done:
      84    24837984 :         if (fde->busy) {
      85    22413507 :                 return -1;
      86             :         }
      87     2333719 :         fde->wrapper = NULL;
      88             : 
      89     2333719 :         return 0;
      90             : }
      91             : 
      92    16091447 : struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
      93             :                                        int fd, uint16_t flags,
      94             :                                        tevent_fd_handler_t handler,
      95             :                                        void *private_data,
      96             :                                        const char *handler_name,
      97             :                                        const char *location)
      98             : {
      99       56815 :         struct tevent_fd *fde;
     100             : 
     101             :         /* tevent will crash later on select() if we save
     102             :          * a negative file descriptor. Better to fail here
     103             :          * so that consumers will be able to debug it
     104             :          */
     105    16091447 :         if (fd < 0) return NULL;
     106             : 
     107    16091447 :         fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
     108    16091447 :         if (!fde) return NULL;
     109             : 
     110    16091447 :         *fde = (struct tevent_fd) {
     111             :                 .event_ctx      = ev,
     112             :                 .fd             = fd,
     113             :                 .flags          = flags,
     114             :                 .handler        = handler,
     115             :                 .private_data   = private_data,
     116             :                 .handler_name   = handler_name,
     117             :                 .location       = location,
     118             :         };
     119             : 
     120    16091447 :         tevent_trace_fd_callback(fde->event_ctx, fde, TEVENT_EVENT_TRACE_ATTACH);
     121    16091447 :         DLIST_ADD(ev->fd_events, fde);
     122    16091447 :         tevent_common_fd_mpx_reinit(fde);
     123             : 
     124    16091447 :         talloc_set_destructor(fde, tevent_common_fd_destructor);
     125             : 
     126             : 
     127    16091447 :         return fde;
     128             : }
     129    38368968 : uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde)
     130             : {
     131    38368968 :         return fde->flags;
     132             : }
     133             : 
     134           0 : void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
     135             : {
     136           0 :         if (fde->flags == flags) return;
     137           0 :         fde->flags = flags;
     138             : }
     139             : 
     140    10240215 : void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
     141             :                                    tevent_fd_close_fn_t close_fn)
     142             : {
     143    10240215 :         fde->close_fn = close_fn;
     144    10240215 : }
     145             : 
     146   167764756 : int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
     147             :                                     bool *removed)
     148             : {
     149   167764756 :         struct tevent_context *handler_ev = fde->event_ctx;
     150             : 
     151   167764756 :         if (removed != NULL) {
     152           0 :                 *removed = false;
     153             :         }
     154             : 
     155   167764756 :         if (fde->event_ctx == NULL) {
     156           0 :                 return 0;
     157             :         }
     158             : 
     159   167764756 :         fde->busy = true;
     160   167764756 :         if (fde->wrapper != NULL) {
     161           4 :                 handler_ev = fde->wrapper->wrap_ev;
     162             : 
     163           4 :                 tevent_wrapper_push_use_internal(handler_ev, fde->wrapper);
     164           4 :                 fde->wrapper->ops->before_fd_handler(
     165           0 :                                         fde->wrapper->wrap_ev,
     166           0 :                                         fde->wrapper->private_state,
     167           0 :                                         fde->wrapper->main_ev,
     168             :                                         fde,
     169             :                                         flags,
     170             :                                         fde->handler_name,
     171             :                                         fde->location);
     172             :         }
     173   167764756 :         tevent_trace_fd_callback(fde->event_ctx, fde, TEVENT_EVENT_TRACE_BEFORE_HANDLER);
     174   167764756 :         fde->handler(handler_ev, fde, flags, fde->private_data);
     175   167685676 :         if (fde->wrapper != NULL) {
     176           4 :                 fde->wrapper->ops->after_fd_handler(
     177           0 :                                         fde->wrapper->wrap_ev,
     178           0 :                                         fde->wrapper->private_state,
     179           0 :                                         fde->wrapper->main_ev,
     180             :                                         fde,
     181             :                                         flags,
     182             :                                         fde->handler_name,
     183             :                                         fde->location);
     184           4 :                 tevent_wrapper_pop_use_internal(handler_ev, fde->wrapper);
     185             :         }
     186   167685676 :         fde->busy = false;
     187             : 
     188   167685676 :         if (fde->destroyed) {
     189    13629144 :                 talloc_set_destructor(fde, NULL);
     190    13629144 :                 TALLOC_FREE(fde);
     191    13629144 :                 if (removed != NULL) {
     192           0 :                         *removed = true;
     193             :                 }
     194             :         }
     195             : 
     196   138552979 :         return 0;
     197             : }
     198             : 
     199      783282 : void tevent_fd_set_tag(struct tevent_fd *fde, uint64_t tag)
     200             : {
     201      783282 :         if (fde == NULL) {
     202           0 :                 return;
     203             :         }
     204             : 
     205      783282 :         fde->tag = tag;
     206             : }
     207             : 
     208      932293 : uint64_t tevent_fd_get_tag(const struct tevent_fd *fde)
     209             : {
     210      932293 :         if (fde == NULL) {
     211           0 :                 return 0;
     212             :         }
     213             : 
     214      932293 :         return fde->tag;
     215             : }

Generated by: LCOV version 1.14