mirror of
https://github.com/samba-team/samba.git
synced 2025-11-25 00:23:52 +03:00
r13482: Push the FAM notification file descriptor into the select
set to avoid unnecessary polling.
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
c15f1d553f
commit
1dce945ccb
@@ -1581,6 +1581,7 @@ struct cnotify_fns {
|
||||
BOOL (*check_notify)(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *data, time_t t);
|
||||
void (*remove_notify)(void *data);
|
||||
int select_time;
|
||||
int notification_fd;
|
||||
};
|
||||
|
||||
#include "smb_macros.h"
|
||||
|
||||
@@ -206,6 +206,15 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
|
||||
return True;
|
||||
}
|
||||
|
||||
int change_notify_fd(void)
|
||||
{
|
||||
if (cnotify) {
|
||||
return cnotify->notification_fd;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Initialise the change notify subsystem.
|
||||
****************************************************************************/
|
||||
|
||||
@@ -63,9 +63,30 @@ static int global_fc_generation;
|
||||
#define FAM_TRACE 8
|
||||
#define FAM_TRACE_LOW 10
|
||||
|
||||
#define FAM_NOTIFY_CHECK_TIMEOUT 1 /* secs */
|
||||
#define FAM_EVENT_DRAIN ((uint32_t)(-1))
|
||||
|
||||
static void * fam_register_notify(connection_struct * conn,
|
||||
char * path,
|
||||
uint32 flags);
|
||||
|
||||
static BOOL fam_check_notify(connection_struct * conn,
|
||||
uint16_t vuid,
|
||||
char * path,
|
||||
uint32_t flags,
|
||||
void * data,
|
||||
time_t when);
|
||||
|
||||
static void fam_remove_notify(void * data)
|
||||
|
||||
static struct cnotify_fns global_fam_notify =
|
||||
{
|
||||
fam_register_notify,
|
||||
fam_check_notify,
|
||||
fam_remove_notify,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
/* Turn a FAM event code into a string. Don't rely on specific code values,
|
||||
* because that might not work across all flavours of FAM.
|
||||
*/
|
||||
@@ -110,6 +131,7 @@ fam_check_reconnect(void)
|
||||
}
|
||||
}
|
||||
|
||||
global_fam_notify.notification_fd = FAMCONNECTION_GETFD(&global_fc);
|
||||
return(True);
|
||||
}
|
||||
|
||||
@@ -420,18 +442,6 @@ fam_remove_notify(void * data)
|
||||
|
||||
struct cnotify_fns * fam_notify_init(void)
|
||||
{
|
||||
static struct cnotify_fns global_fam_notify =
|
||||
{
|
||||
fam_register_notify,
|
||||
fam_check_notify,
|
||||
fam_remove_notify,
|
||||
FAM_NOTIFY_CHECK_TIMEOUT
|
||||
};
|
||||
|
||||
/* TODO: rather than relying on FAM_NOTIFY_CHECK_TIMEOUT, we should have an
|
||||
* API to push the FAM fd into the global server fd set.
|
||||
*/
|
||||
|
||||
FAMCONNECTION_GETFD(&global_fc) = -1;
|
||||
|
||||
if (!fam_test_connection()) {
|
||||
|
||||
@@ -230,6 +230,7 @@ struct cnotify_fns *hash_notify_init(void)
|
||||
cnotify.check_notify = hash_check_notify;
|
||||
cnotify.remove_notify = hash_remove_notify;
|
||||
cnotify.select_time = lp_change_notify_timeout();
|
||||
cnotify.notification_fd = -1;
|
||||
|
||||
return &cnotify;
|
||||
}
|
||||
|
||||
@@ -232,6 +232,7 @@ struct cnotify_fns *kernel_notify_init(void)
|
||||
cnotify.check_notify = kernel_check_notify;
|
||||
cnotify.remove_notify = kernel_remove_notify;
|
||||
cnotify.select_time = -1;
|
||||
cnotify.notification_fd = -1;
|
||||
|
||||
/* the signal can start off blocked due to a bug in bash */
|
||||
BlockSignals(False, RT_SIGNAL_NOTIFY);
|
||||
|
||||
@@ -240,21 +240,16 @@ BOOL downgrade_oplock(files_struct *fsp)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Setup the listening set of file descriptors for an oplock break
|
||||
message either from the UDP socket or from the kernel. Returns the maximum
|
||||
fd used.
|
||||
Return the fd (if any) used for receiving oplock notifications.
|
||||
****************************************************************************/
|
||||
|
||||
int setup_oplock_select_set( fd_set *fds)
|
||||
int oplock_notify_fd(void)
|
||||
{
|
||||
int maxfd = 0;
|
||||
|
||||
if (koplocks && koplocks->notification_fd != -1) {
|
||||
FD_SET(koplocks->notification_fd, fds);
|
||||
maxfd = MAX(maxfd, koplocks->notification_fd);
|
||||
if (koplocks) {
|
||||
return koplocks->notification_fd;
|
||||
}
|
||||
|
||||
return maxfd;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -318,6 +318,20 @@ static void async_processing(void)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Add a fd to the set we will be select(2)ing on.
|
||||
****************************************************************************/
|
||||
|
||||
static int select_on_fd(int fd, int maxfd, fd_set *fds)
|
||||
{
|
||||
if (fd != -1) {
|
||||
FD_SET(fd, fds);
|
||||
maxfd = MAX(maxfd, fd);
|
||||
}
|
||||
|
||||
return maxfd;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Do a select on an two fd's - with timeout.
|
||||
|
||||
@@ -344,7 +358,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
|
||||
fd_set fds;
|
||||
int selrtn;
|
||||
struct timeval to = timeval_set(SMBD_SELECT_TIMEOUT, 0);
|
||||
int maxfd;
|
||||
int maxfd = 0;
|
||||
|
||||
smb_read_error = 0;
|
||||
|
||||
@@ -437,10 +451,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
|
||||
}
|
||||
}
|
||||
|
||||
FD_SET(smbd_server_fd(),&fds);
|
||||
maxfd = setup_oplock_select_set(&fds);
|
||||
maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds);
|
||||
maxfd = select_on_fd(change_notify_fd(), maxfd, &fds);
|
||||
maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds);
|
||||
|
||||
selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,&to);
|
||||
selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);
|
||||
|
||||
/* if we get EINTR then maybe we have received an oplock
|
||||
signal - treat this as select returning 1. This is ugly, but
|
||||
|
||||
Reference in New Issue
Block a user