110 likes | 260 Views
The ‘fasync()’ driver-method. Two viewpoints on implementing asynchronous notification: the application’s and the driver’s . Chapter 6 of LDD3.
E N D
The ‘fasync()’ driver-method Two viewpoints on implementing asynchronous notification: the application’s and the driver’s
Chapter 6 of LDD3 • Our textbook’s chapter on Enhanced Char Drivers provides details on how programs can utilize asynchronous notification when it’s supported by the underlying drivers • We will survey the essential elements and we will present a pair of demonstrations: • An application: ‘pipedemo.cpp’ • A device-driver: ‘nicasync.c’
The ‘fcntl()’ library-function #include <sys/fcntl.h> // the header-file int fcntl( int fd, int cmd ); // gets info int fcntl( int fd, int cmd, int arg ); // sets info F_GETOWN and F_SETOWN // owner F_GETFL and F_SETFL // flags F_GETSIG and F_SETSIG // signal
The ‘sigaction()’ library-function #include <signal.h> // the header-file struct sigaction sa = {0}, oa; // data-object void action( int signo, siginfo_t *si, void *data ); sigemptyset( &sa.sa_mask ); sa.sa_sigaction = action; sa.sa_flags = SA_SIGINFO; sigaction( SIGnumber, &sa, &oa );
Enabling async notification int fd = open( devicename, O_RDWR ); fcntl( fd, F_SETOWN, getpid() ); int flags = fcntl( fd, F_GETFL ); fcntl( fd, F_SETFL, flags | FASYNC ); fcntl( fd, F_SETSIG, SIGnumber ); pause(); // go to sleep until signaled
The device-driver duties #include <linux/fs.h> // for kill_fasync() int my_signal = SIGIO; // default signal-ID struct fasync_struct *my_asqueue; int my_fasync( int fd, struct file *fp, int on ) { return fasync_helper( fd, fp, on, &my_asqueue ); } // plus a few modifications in other driver-methods
Interrupt-handler: ‘my_isr()’ • Use this function to issue the notification when a new network-packet is received: kill_fasync( &asqueue, SIGno, POLL_IN ); • Use this function to issue the notification when a packet-transmission completes: kill_fasync( &asqueue, SIGno, POLL_OUT );
‘release()’ • Use: fasync_helper( -1, file, 0, &asqueue ); // to disable asynchronous notifications for // this device-file’s descriptor
Non-blocking i/o, signal wakeups • Our driver-modifications in ‘nicasync.c’ included support for non-blocking reads and non-blocking writes (one line each) • Our driver-modifications in ‘nicasync.c’ now support the handling of signals that awaken tasks from read or write sleeps (i.e., if ( wait_event_interruptible() < 0 ) return -ERESTARTSYS
In-class exercise • Compile and install our ‘nicasync.c’ Linux module (a RealTek driver with ‘fasync()’) • Then write a revised version of our earlier ‘trychat.cpp’ demo-program that uses the asynchronous notification capability for handling the multiplexed input (from the network device and the keyboard device)
The ‘trychat’ packet-format ethernet frame-header (14 bytes) network-order: big-endian dest’n hardware address (6 bytes) source hardware address (6 bytes) type (2 bytes) 0x0635 nicchat protocol frame-data (50 bytes) local-order: little-endian count (2 bytes)