LCOV - code coverage report
Current view: top level - lib/tevent - tevent_fd.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 73 89 82.0 %
Date: 2023-11-21 12:31:41 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        5056 : const char *tevent_common_fd_str(struct tevent_common_fd_buf *buf,
      34             :                                  const char *description,
      35             :                                  const struct tevent_fd *fde)
      36             : {
      37       15166 :         snprintf(buf->buf, sizeof(buf->buf),
      38             :                  "%s[fde=%p,"
      39             :                  "fd=%d,flags=0x%x(%s%s%s),%s]",
      40        5056 :                  description, fde, fde->fd,
      41        5054 :                  fde->flags,
      42        5054 :                  (fde->flags & TEVENT_FD_ERROR) ? "E" : "",
      43        5054 :                  (fde->flags & TEVENT_FD_READ) ? "R" : "",
      44        5056 :                  (fde->flags & TEVENT_FD_WRITE) ? "W" : "",
      45        5056 :                  fde->handler_name);
      46        5056 :         return buf->buf;
      47             : }
      48             : 
      49    24488122 : int tevent_common_fd_destructor(struct tevent_fd *fde)
      50             : {
      51    24488122 :         struct tevent_fd *primary = NULL;
      52             : 
      53    24488122 :         if (fde->destroyed) {
      54     8617666 :                 tevent_common_check_double_free(fde, "tevent_fd double free");
      55     8617666 :                 goto done;
      56             :         }
      57    15870456 :         fde->destroyed = true;
      58             : 
      59             :         /*
      60             :          * The caller should have cleared it from any mpx relationship
      61             :          */
      62    15870456 :         primary = tevent_common_fd_mpx_primary(fde);
      63    15870456 :         if (primary != fde) {
      64           0 :                 tevent_abort(fde->event_ctx,
      65             :                         "tevent_common_fd_destructor: fde not mpx primary");
      66    15870456 :         } 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    15870456 :         if (fde->event_ctx) {
      72    14837963 :                 tevent_trace_fd_callback(fde->event_ctx, fde, TEVENT_EVENT_TRACE_DETACH);
      73    14837963 :                 DLIST_REMOVE(fde->event_ctx->fd_events, fde);
      74             :         }
      75             : 
      76    15870456 :         if (fde->close_fn) {
      77    10143446 :                 fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data);
      78    10143446 :                 fde->fd = -1;
      79    10143446 :                 fde->close_fn = NULL;
      80             :         }
      81             : 
      82    15870456 :         fde->event_ctx = NULL;
      83    24488122 : done:
      84    24488122 :         if (fde->busy) {
      85    22128030 :                 return -1;
      86             :         }
      87     2267602 :         fde->wrapper = NULL;
      88             : 
      89     2267602 :         return 0;
      90             : }
      91             : 
      92    15898180 : 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       57327 :         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    15898180 :         if (fd < 0) return NULL;
     106             : 
     107    15898180 :         fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
     108    15898180 :         if (!fde) return NULL;
     109             : 
     110    15898180 :         *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    15898180 :         tevent_trace_fd_callback(fde->event_ctx, fde, TEVENT_EVENT_TRACE_ATTACH);
     121    15898180 :         DLIST_ADD(ev->fd_events, fde);
     122    15898180 :         tevent_common_fd_mpx_reinit(fde);
     123             : 
     124    15898180 :         talloc_set_destructor(fde, tevent_common_fd_destructor);
     125             : 
     126             : 
     127    15898180 :         return fde;
     128             : }
     129    37943720 : uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde)
     130             : {
     131    37943720 :         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    10204428 : void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
     141             :                                    tevent_fd_close_fn_t close_fn)
     142             : {
     143    10204428 :         fde->close_fn = close_fn;
     144    10204428 : }
     145             : 
     146   164388432 : int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
     147             :                                     bool *removed)
     148             : {
     149   164388432 :         struct tevent_context *handler_ev = fde->event_ctx;
     150             : 
     151   164388432 :         if (removed != NULL) {
     152           0 :                 *removed = false;
     153             :         }
     154             : 
     155   164388432 :         if (fde->event_ctx == NULL) {
     156           0 :                 return 0;
     157             :         }
     158             : 
     159   164388432 :         fde->busy = true;
     160   164388432 :         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   164388432 :         tevent_trace_fd_callback(fde->event_ctx, fde, TEVENT_EVENT_TRACE_BEFORE_HANDLER);
     174   164388432 :         fde->handler(handler_ev, fde, flags, fde->private_data);
     175   164310462 :         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   164310462 :         fde->busy = false;
     187             : 
     188   164310462 :         if (fde->destroyed) {
     189    13525001 :                 talloc_set_destructor(fde, NULL);
     190    13525001 :                 TALLOC_FREE(fde);
     191    13525001 :                 if (removed != NULL) {
     192           0 :                         *removed = true;
     193             :                 }
     194             :         }
     195             : 
     196   135279134 :         return 0;
     197             : }
     198             : 
     199      691117 : void tevent_fd_set_tag(struct tevent_fd *fde, uint64_t tag)
     200             : {
     201      691117 :         if (fde == NULL) {
     202           0 :                 return;
     203             :         }
     204             : 
     205      691117 :         fde->tag = tag;
     206             : }
     207             : 
     208      829885 : uint64_t tevent_fd_get_tag(const struct tevent_fd *fde)
     209             : {
     210      829885 :         if (fde == NULL) {
     211           0 :                 return 0;
     212             :         }
     213             : 
     214      829885 :         return fde->tag;
     215             : }

Generated by: LCOV version 1.14