2009-01-03 13:18:14 +03:00
/*
Unix SMB / CIFS implementation .
common events code for fd events
2009-02-16 10:52:06 +03:00
Copyright ( C ) Stefan Metzmacher 2009
2009-01-03 13:18:14 +03:00
2009-08-18 13:53:42 +04:00
* * NOTE ! The following LGPL license applies to the tevent
2009-02-16 10:52:06 +03:00
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
2009-01-03 13:18:14 +03:00
2009-02-16 10:52:06 +03:00
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 3 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
2009-01-03 13:18:14 +03:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2009-02-16 10:52:06 +03:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
2009-01-03 13:18:14 +03:00
2009-02-16 10:52:06 +03:00
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2009-01-03 13:18:14 +03:00
*/
# include "replace.h"
2019-01-08 17:25:22 +03:00
# define TEVENT_DEPRECATED 1
2009-01-03 13:18:14 +03:00
# include "tevent.h"
# include "tevent_internal.h"
# include "tevent_util.h"
2009-01-05 19:36:50 +03:00
int tevent_common_fd_destructor ( struct tevent_fd * fde )
{
2014-07-22 16:45:33 +04:00
if ( fde - > destroyed ) {
tevent_common_check_double_free ( fde , " tevent_fd double free " ) ;
goto done ;
}
fde - > destroyed = true ;
2009-01-05 19:36:50 +03:00
if ( fde - > event_ctx ) {
2021-06-01 15:10:05 +03:00
tevent_trace_fd_callback ( fde - > event_ctx , fde , TEVENT_EVENT_TRACE_DETACH ) ;
2009-01-05 19:36:50 +03:00
DLIST_REMOVE ( fde - > event_ctx - > fd_events , fde ) ;
}
if ( fde - > close_fn ) {
fde - > close_fn ( fde - > event_ctx , fde , fde - > fd , fde - > private_data ) ;
fde - > fd = - 1 ;
2014-07-22 16:45:33 +04:00
fde - > close_fn = NULL ;
}
fde - > event_ctx = NULL ;
done :
if ( fde - > busy ) {
return - 1 ;
2009-01-05 19:36:50 +03:00
}
2014-07-22 18:51:38 +04:00
fde - > wrapper = NULL ;
2009-01-05 19:36:50 +03:00
return 0 ;
}
struct tevent_fd * tevent_common_add_fd ( struct tevent_context * ev , TALLOC_CTX * mem_ctx ,
int fd , uint16_t flags ,
tevent_fd_handler_t handler ,
void * private_data ,
const char * handler_name ,
const char * location )
{
struct tevent_fd * fde ;
2011-02-14 18:29:49 +03:00
/* tevent will crash later on select() if we save
* a negative file descriptor . Better to fail here
* so that consumers will be able to debug it
*/
if ( fd < 0 ) return NULL ;
2009-01-05 19:36:50 +03:00
fde = talloc ( mem_ctx ? mem_ctx : ev , struct tevent_fd ) ;
if ( ! fde ) return NULL ;
2014-10-23 09:15:14 +04:00
* fde = ( struct tevent_fd ) {
. event_ctx = ev ,
. fd = fd ,
. flags = flags ,
. handler = handler ,
. private_data = private_data ,
. handler_name = handler_name ,
. location = location ,
} ;
2009-01-05 19:36:50 +03:00
2021-06-01 15:10:05 +03:00
tevent_trace_fd_callback ( fde - > event_ctx , fde , TEVENT_EVENT_TRACE_ATTACH ) ;
2009-01-05 19:36:50 +03:00
DLIST_ADD ( ev - > fd_events , fde ) ;
talloc_set_destructor ( fde , tevent_common_fd_destructor ) ;
2021-06-01 15:10:05 +03:00
2009-01-05 19:36:50 +03:00
return fde ;
}
2009-01-03 13:18:14 +03:00
uint16_t tevent_common_fd_get_flags ( struct tevent_fd * fde )
{
return fde - > flags ;
}
void tevent_common_fd_set_flags ( struct tevent_fd * fde , uint16_t flags )
{
if ( fde - > flags = = flags ) return ;
fde - > flags = flags ;
}
2009-01-03 13:27:00 +03:00
void tevent_common_fd_set_close_fn ( struct tevent_fd * fde ,
tevent_fd_close_fn_t close_fn )
{
fde - > close_fn = close_fn ;
}
2014-07-22 16:45:33 +04:00
int tevent_common_invoke_fd_handler ( struct tevent_fd * fde , uint16_t flags ,
bool * removed )
{
2014-07-22 18:51:38 +04:00
struct tevent_context * handler_ev = fde - > event_ctx ;
2014-07-22 16:45:33 +04:00
if ( removed ! = NULL ) {
* removed = false ;
}
if ( fde - > event_ctx = = NULL ) {
return 0 ;
}
fde - > busy = true ;
2014-07-22 18:51:38 +04:00
if ( fde - > wrapper ! = NULL ) {
handler_ev = fde - > wrapper - > wrap_ev ;
tevent_wrapper_push_use_internal ( handler_ev , fde - > wrapper ) ;
fde - > wrapper - > ops - > before_fd_handler (
fde - > wrapper - > wrap_ev ,
fde - > wrapper - > private_state ,
fde - > wrapper - > main_ev ,
fde ,
flags ,
fde - > handler_name ,
fde - > location ) ;
}
2021-06-01 15:10:05 +03:00
tevent_trace_fd_callback ( fde - > event_ctx , fde , TEVENT_EVENT_TRACE_BEFORE_HANDLER ) ;
2014-07-22 18:51:38 +04:00
fde - > handler ( handler_ev , fde , flags , fde - > private_data ) ;
if ( fde - > wrapper ! = NULL ) {
fde - > wrapper - > ops - > after_fd_handler (
fde - > wrapper - > wrap_ev ,
fde - > wrapper - > private_state ,
fde - > wrapper - > main_ev ,
fde ,
flags ,
fde - > handler_name ,
fde - > location ) ;
tevent_wrapper_pop_use_internal ( handler_ev , fde - > wrapper ) ;
}
2014-07-22 16:45:33 +04:00
fde - > busy = false ;
if ( fde - > destroyed ) {
talloc_set_destructor ( fde , NULL ) ;
TALLOC_FREE ( fde ) ;
if ( removed ! = NULL ) {
* removed = true ;
}
}
return 0 ;
}
2021-06-01 14:57:45 +03:00
void tevent_fd_set_tag ( struct tevent_fd * fde , uint64_t tag )
{
if ( fde = = NULL ) {
return ;
}
fde - > tag = tag ;
}
uint64_t tevent_fd_get_tag ( const struct tevent_fd * fde )
{
if ( fde = = NULL ) {
return 0 ;
}
return fde - > tag ;
}