Glib study Note 3-core glib application support: understanding of Io channels in glib

Source: Internet
Author: User
Tags gtk

Original article link

The GUI system is event-driven. An event loop process must be used to obtain and process events. The same is true for GTK. The GTK event loop process is provided by glib, while iochannel is a means of integrating Io events into events in glib.

Iochannel can convert the events that occur on file descriptors, pipelines, and sockets specified by the developer to internal events of glib, so as to process Io events and user interaction in a unified way in the program.

Iochannel supports readable, writable, Urgent Data arrival, error, and hanging. Because iochannel is built based on file descriptors, pipelines, and sockets, the methods provided by iochannel include both the similarities and differences between the three.

So how can I add an iochannel to a program based on GTK or glib?

Generally, the steps are as follows:

1. Create a file descriptor.

You can open a common file, create a pipeline, or open a socket. The result is a file descriptor.

2. Create an iochannel and set the data encoding.

Iochannel is created using the following function:

Giochannel * g_io_channel_unix_new (int fd );

For example:

Io_channel = g_io_channel_unix_new (FD );

After creation, you can set the data encoding. I am not very clear about data encoding. Generally, I set the encoding to null so that no data is processed when I use the read/write functions provided by iochannel. The encoding setting function is as follows:

Giostatus g_io_channel_set_encoding (giochannel * channel, const gchar * encoding, gerror ** error );

For example, set the encoding to NULL:

G_io_channel_set_encoding (io_channel, null, & ERR );

3. Add the events on the file descriptor you want to process to the event loop.

Add the specified iochannel event to the event loop using the following function:

Guint g_io_add_watch (giochannel * channel, giocondition condition, giofunc func, gpointer user_data );

Giocondition includes g_io_in, g_io_out, g_io_pri, g_io_err, g_io_hup, and g_io_nval. You can specify multiple events simultaneously through their or operations. Of course, the callback function should determine which event caused the callback.

The callback function of iochannel is prototype:

Gboolean (* giofunc) (giochannel * Source, giocondition condition, gpointer data );

The second parameter is the value of the event that causes the callback.

The above step 1 serves to create a button, and step 2 serves to add an event to the event loop with g_signal_connect. To do these three jobs well, there are two more jobs:

1. Write the callback function.

In the callback function, you can use the Read and Write functions provided by iochannel, or use the file descriptor obtained by g_io_channel_unix_get_fd () to perform normal Io operations.

2. Exit the event loop and disable iochannel.

When the program ends or the file descriptor is useless, disable iochannel. You must exit the event loop before closing, and use g_source_remove (source_id) to complete the exit action. Source_id is the return value of g_io_add_watch.

Then you can close the iochannel, and use g_io_channel_shutdown (io_channel, true, null) to complete the closing action.

After the iochannel is disabled, the memory occupied by the iochannel has not been released. g_io_channel_unref (io_channel) is used to reduce the iochannel reference counter so that it is 0, and glib will automatically release the iochannel.

Based on your application, my suggestion is to use the socket file descriptor to create an iochannel after connecting to the server, and create a callback function for all events except Data writable (g_io_out, add an event loop. When data exists, it is passively read and actively sent when data is sent.

One iochannel can only be bound to one socket.

On the server side, an iochannel is created using FD (set as listen_fd) after listen.

When there is a connection, iochannel is displayed as listen_fd readable. In the callback function, accept is used to obtain a connection FD (set to connect_fd ). Create an iochannel for each connect_fd.

In short, the listen_fd callback function is used for accept; The connect_fd callback function is used for read and write, and each connect_fd callback function is the same.

Disable the iochannel after connect_fd is disabled.

You may use g_idle_add () to add a garbage collection function to disable iochannel.

Because the iochannel cannot be shutdown in the callback function of connect_fd.

The client must note that the connect timeout time is relatively long, and threads may be used to solve this problem.

If you want to implement "continuously read the serial port after the button event starts, until the serial port is shut down and the key event starts", using the while statement is not feasible. It is not feasible to add a non-blocking event only, because in the while loop, your program will not respond to the button event.

Multithreading can solve the problem, but try not to use it.

Iochannel is the most suitable. The method is roughly as follows:

1. Open the serial port in non-blocking mode. Non-blocking is required. The reason is described below.

FD = open ("/dev/ttys0", o_rdwr | o_nonblock, 0644 );

2. Create an iochannel.

Io_channel = g_io_channel_unix_new (FD );

G_io_channel_set_encoding (io_channel, null, & ERR);/* optional */

3. Add the file descriptor readable events to the program's event loop:

Source_id = g_io_add_watch (io_channel, g_io_in, read_ttys, null );

4. After completing these steps, you can use read_ttys () to read the serial port data.

You can use read () to directly read serial data, or use the iochannel provided by glib to read function reads.

However, it must be noted that the read operation can be completed only when there is no data readable in cyclic reading and an error is returned. This is because there is a buffer in the kernel. If all the data is not read at a time, you should
The data read in this callback will not be read until the next time. The data traffic of the serial port is not large. This solution is not required and may not be a problem, but it is better to be safe. Use non-blocking when opening the serial port above
The plug-in is used to complete the data.

5. When a stop read event occurs, the callback function should do the following:

* (1). Exit the event loop: g_source_remove (source_id );

* (2). Disable io_channel: g_io_channel_shutdown (io_channel, true, null );

* (3). Release io_channel: g_io_channel_unref (io_channel );

Disabling the iochannel operation will disable the file descriptor.

6. Others:

The order of enabling and disabling iochannels is unchangeable.

If you only want to temporarily not read the file, you can exit the event loop.

It is not guaranteed whether the data that comes after exiting the event loop will be cached in the kernel, or whether all the data during this period will be cached, therefore, when you exit the event loop and add data, you must check whether the data is what you need. (Not guaranteed because I have not performed any tests)

Iochannel is not a new technology. Its foundation is select/poll. Compare the event options and
What select/poll provides is clear. For select/poll, choose MAN 2 select_tut or man 2 poll.

The method mentioned above applies to other file descriptors. I used it on socket.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.