Topic: Select the bottom of the database.
First, from the database query data angle, probably the framework (premise: The client needs to send query statements to the server side)
1. Receive statement lookup SQL plan cache
If there is no-_-| |
2. Check statement legality (check for SQL statement syntax)
3. Check the language meaning (for the SQL statement contains the table name, field name)
4. Get Object Resolution Lock
5. Check whether user rights have access to data
To explore, I can't help but think, usually write SQL statements, this is the AH.
6. Determine the best execution plan (self optimization, very limited), while the current SQL language
Sentence and best execution plan save to cache
Second, from the prototype of select to consider
The Select () prototype is primarily based on the Fd_set type. Fd_set is a collection of file descriptor (FD) that represents an FD, and operates on the following four macro definitions for the Fd_set type:
Fd_set set;
Fd_zero (&set); /sets the set to 00000000 for all position 0, such as set in memory for 8 bits
Fd_set (0, &set); /* Sets the No. 0 position of Set 1, such as set is 00000000, now becomes 10000000, so that the Fd==1 file description is added to the set.
FD_CLR (4, &set); /* Sets the 4th position of set to 0, such as set is 10001000, now becomes 10000000, so that the fd==4 file descriptor is removed from the set
Fd_isset (5, &set); /* Test set 5th bit is 1, if set is originally 10000100, then return Non-zero, indicating that fd==5 's file descriptor is in set; otherwise return 0*/
The interface of the SELECT function:
int select (int Nfds, fd_set readset, fd_set *writeset,fd_set exceptset, struct timeval);
Function:
Tests the specified FD to read. can be written. There are unusual conditions to be processed.
Parameters:
1.nfds: Need to check the number of file description (that is, check to Fd_set), the value should be greater than the maximum FD in the three groups of Fd_set, generally set to three groups of fd_set in the maximum FD value plus 1 (as in Readset,writeset, The largest FD in the Exceptset is 5, then nfds=6, because FD starts at 0. This value is designed to improve efficiency so that functions do not have to check all 1024 bits of fd_set.
2.readset: A set of file descriptors used to check readability.
3.writeset: A set of file descriptors used to check for a writable character.
4.exceptset: A file descriptor used to check for unusual conditions.
5.timeout: There are three possible ways:
1. Timeout=null (blocking: Until a FD bit is set to 1 function to return)
The structure pointed to by 2.timeout is set to a Non-zero time (wait fixed time: There is a FD bit placed
is 1 or time runs out, functions are returned)
3. The structure pointed to by timeout, the time set to 0 (non-blocking: function check after each FD immediately return)
return value:
Returns the total number of FD with the corresponding bit remaining at 1.
Remarks:
All three groups of Fd_set will have some FD position 0, only those with readable, writable and abnormal conditions to be treated are still 1.
General procedure for using the SELECT function: Invoke macro Fd_zero The specified Fd_set 0-–> macros fd_set add FD to fd_set--> then call the function Select to test all the FD in the Fd_set, and then use the macro Fd_ Isset checks to see if an FD is still 1 after the function select call.
Single file descriptive word readability
int isready (int fd)
{
int RC;
Fd_set FDS;
struct Timeval TV;
Fd_zero (&fds);
Fd_set (Fd,&fds);
tv.tv_sec = tv.tv_usec = 0;
rc = Select (fd+1, &fds, NULL, NULL, &TV);
if (RC < 0)//error
return-1;
Return Fd_isset (Fd,&fds)? 1:0;
}
The application invokes the Select () function, and the system calls into the kernel and into:
Syscall_define5 (sys_select)--> core_sys_select-–> do_select ()
Syscall_define5 (SELECT, int, n, fd_set __user, INP, Fd_set __user, OUTP,
Fd_set __user, exp, struct timeval __user, TVP)//n for file descriptors
{
struct Timespec end_time, *to = NULL;
struct Timeval TV;
int ret;
if (TVP) {
if (Copy_from_user (&TV, TVP, sizeof (TV))
Return-efault;
to = &end_time;
if (To, poll_select_set_timeout
Tv.tv_sec + (TV.TV_USEC/USEC_PER_SEC),
(tv.tv_usec% usec_per_sec) * nsec_per_usec))
return-einval;
}
ret = Core_sys_select (n, INP, OUTP, exp, to);
ret = poll_select_copy_remaining (&end_time, TVP, 1, ret);
return ret;
}
Do_select is called in the Core_sys_select () function:
int do_select (int n, fd_set_bits *fds, struct timespec *end_time)
{
ktime_t expire, *to = NULL;
struct Poll_wqueues table;
Poll_table *wait;
int retval, I, timed_out = 0;
unsigned long slack = 0;
Rcu_read_lock ();
retval = MAX_SELECT_FD (n, FDS);
Rcu_read_unlock ();
if (retval < 0) return retval;
n = retval;
Poll_initwait (&table);//Initialize structure, mainly initialize poll_wait callback function __pollwait wait = &table.pt;
if (end_time &&!end_time->tv_sec &&!end_time->tv_nsec) {wait = NULL;
Timed_out = 1;
} if (End_time &&!timed_out) slack = estimate_accuracy (end_time);
retval = 0; for (;;)
{unsigned long *rinp, *ROUTP, *rexp, *INP, *OUTP, *exp; INP = fds->in; OUTP = fds->out;
Exp = fds->ex; RINP = fds->res_in; ROUTP = fds->res_out;
Rexp = fds->res_ex; for (i = 0; i < n; ++rinp, ++ROUTP, ++rexp) {unsigned long, out, ex, all_bits, bit = 1, mas
K, J;
unsigned long res_in = 0, res_out = 0, res_ex = 0; const struct File_operations *f_op = NULL;
struct file *file = NULL; in = *inp++; out = *outp++;
ex = *exp++; All_bits = in | Out |
Ex
if (all_bits = = 0) {i + = __nfdbits;
Continue for (j = 0; j < __nfdbits; ++j, ++i, bit <<= 1) {int
fput_needed;
if (i >= n) break; if (!) (
Bit & all_bits)) continue;
File = Fget_light (i, &fput_needed);
if (file) {f_op = file->f_op;
mask = Default_pollmask; if (f_op && f_op->poll) {Wait_key_set (wai
T, in, out, bit); Mask = (*f_op->poll) (file, wait););//Call the poll_wait process,//That is to add the driver waiting queue header Add to the entry in the Poll_wqueues and add the wait queue entry to//current mileage to the wait queue header. Each waiting queue header occupies a entry} fput_light (file,
fput_needed);
if ((Mask & Pollin_set) && (in & bit) {//If there is a signal to set, record, write back to the corresponding item, set the retval to jump out of the loop
res_in |= bit;
retval++;
wait = NULL; } if (Mask & Pollout_set) && (out & Bit)) {res_out |= bit;
retval++;
wait = NULL;
} if (Mask & Pollex_set) && (ex & Bit) {
RES_EX |= bit;
retval++;
wait = NULL;
}} if (res_in)
*RINP = res_in;
if (res_out) *ROUTP = res_out;
if (res_ex) *rexp = RES_EX;
Cond_resched ()//increase preemption point, schedule other processes, current mileage into sleep wait = NULL;
if (retval | | timed_out | | | signal_pending (current))//out of the loop here, you need to talk about signal_pending break;
if (table.error) {retval = Table.error;
Break }/* If This is the the the the I loop and we have a timeout * given, then we con
Vert to ktime_t and set the to * pointer to the expiry value. *//Read time to wait, wait timeout if (end_time &&!to) {expire = Timesp
Ec_to_ktime (*end_time);
to = &expire; } if (!poll_schedule_timeout (&table, task_interruptible,to, slack)) Timed_out =
1;
Poll_freewait (&table),//Remove the wait queue that was added in poll_wait from the wait queue header, and release the resource return retval;//the call is successful or not. Look at this returned value
}
Do_select's idea is that when the application calls the Select () function, the kernel invokes poll_wait (), adds the current process to the waiting queue for the device, and then sets the application process to sleep. Until the data on the device can be fetched, and then call wake up to wake the application process to get the data.