mirror of
https://github.com/samba-team/samba.git
synced 2025-11-23 20:23:50 +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);
|
BOOL (*check_notify)(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *data, time_t t);
|
||||||
void (*remove_notify)(void *data);
|
void (*remove_notify)(void *data);
|
||||||
int select_time;
|
int select_time;
|
||||||
|
int notification_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "smb_macros.h"
|
#include "smb_macros.h"
|
||||||
|
|||||||
@@ -206,6 +206,15 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int change_notify_fd(void)
|
||||||
|
{
|
||||||
|
if (cnotify) {
|
||||||
|
return cnotify->notification_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Initialise the change notify subsystem.
|
Initialise the change notify subsystem.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
@@ -63,9 +63,30 @@ static int global_fc_generation;
|
|||||||
#define FAM_TRACE 8
|
#define FAM_TRACE 8
|
||||||
#define FAM_TRACE_LOW 10
|
#define FAM_TRACE_LOW 10
|
||||||
|
|
||||||
#define FAM_NOTIFY_CHECK_TIMEOUT 1 /* secs */
|
|
||||||
#define FAM_EVENT_DRAIN ((uint32_t)(-1))
|
#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,
|
/* 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.
|
* 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);
|
return(True);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,18 +442,6 @@ fam_remove_notify(void * data)
|
|||||||
|
|
||||||
struct cnotify_fns * fam_notify_init(void)
|
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;
|
FAMCONNECTION_GETFD(&global_fc) = -1;
|
||||||
|
|
||||||
if (!fam_test_connection()) {
|
if (!fam_test_connection()) {
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ struct cnotify_fns *hash_notify_init(void)
|
|||||||
cnotify.check_notify = hash_check_notify;
|
cnotify.check_notify = hash_check_notify;
|
||||||
cnotify.remove_notify = hash_remove_notify;
|
cnotify.remove_notify = hash_remove_notify;
|
||||||
cnotify.select_time = lp_change_notify_timeout();
|
cnotify.select_time = lp_change_notify_timeout();
|
||||||
|
cnotify.notification_fd = -1;
|
||||||
|
|
||||||
return &cnotify;
|
return &cnotify;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ struct cnotify_fns *kernel_notify_init(void)
|
|||||||
cnotify.check_notify = kernel_check_notify;
|
cnotify.check_notify = kernel_check_notify;
|
||||||
cnotify.remove_notify = kernel_remove_notify;
|
cnotify.remove_notify = kernel_remove_notify;
|
||||||
cnotify.select_time = -1;
|
cnotify.select_time = -1;
|
||||||
|
cnotify.notification_fd = -1;
|
||||||
|
|
||||||
/* the signal can start off blocked due to a bug in bash */
|
/* the signal can start off blocked due to a bug in bash */
|
||||||
BlockSignals(False, RT_SIGNAL_NOTIFY);
|
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
|
Return the fd (if any) used for receiving oplock notifications.
|
||||||
message either from the UDP socket or from the kernel. Returns the maximum
|
|
||||||
fd used.
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int setup_oplock_select_set( fd_set *fds)
|
int oplock_notify_fd(void)
|
||||||
{
|
{
|
||||||
int maxfd = 0;
|
if (koplocks) {
|
||||||
|
return koplocks->notification_fd;
|
||||||
if (koplocks && koplocks->notification_fd != -1) {
|
|
||||||
FD_SET(koplocks->notification_fd, fds);
|
|
||||||
maxfd = MAX(maxfd, koplocks->notification_fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxfd;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Do all async processing in here. This includes kernel oplock messages, change
|
Do all async processing in here. This includes kernel oplock messages, change
|
||||||
notify events etc.
|
notify events etc.
|
||||||
@@ -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.
|
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;
|
fd_set fds;
|
||||||
int selrtn;
|
int selrtn;
|
||||||
struct timeval to = timeval_set(SMBD_SELECT_TIMEOUT, 0);
|
struct timeval to = timeval_set(SMBD_SELECT_TIMEOUT, 0);
|
||||||
int maxfd;
|
int maxfd = 0;
|
||||||
|
|
||||||
smb_read_error = 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 = select_on_fd(smbd_server_fd(), maxfd, &fds);
|
||||||
maxfd = setup_oplock_select_set(&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
|
/* if we get EINTR then maybe we have received an oplock
|
||||||
signal - treat this as select returning 1. This is ugly, but
|
signal - treat this as select returning 1. This is ugly, but
|
||||||
|
|||||||
Reference in New Issue
Block a user