Development Update: multi-axel BETA

Multi-axel project is nearly done, the last stage to finish is ‘testing’. Two major bugs were fixed as I started to use it with Flashgot Firefox addon. So far things are good and fast. This project was ambitious, educative and challenging. Even seasoned developers asked why I chose C/C++ for developing a front-end which I had no answer for other than just to keep it lean. And I ended up having both C and C++ source files on a project that I initially thought to do in 100% C++. Total development time was lower than I thought, it was just around a week, with huge intervals of not working on it because of other work. Even though the program does very trivial stuff, it is not that simple. Here is a brief description of the project plan, and it does not have any kind of document other than what I’m writing here so if anyone is thinking of contributing please read through this carefully.

Each axel process is summoned with the arguments in settings. These include ftp_proxy and http_proxy environment variables even though they are two different variables in the back-end class, in the GUI a single field is for the proxy. This is used for both variables(I was lazy!). Every single one of  the  axel processes are monitored by a thread on a one to one basis. These threads listen to the piped standard out of axel processes and keep reading until they close the standard out, on exit. All data for the GUI is updated from this data. As of now the GUI maintains a separate thread for updating itself, this might change in to callbacks in the future. One major thing I learnt while writing muti-axel is that read() can and will be a major PITA if you do not manage it. It only guarantees 0 on a file descriptor close, it can either block(when using the no block option) or return as soon as called with an integer >0. This makes things worse for listeners, when the buffer is not filled it can’t be managed effectively and a whole lot of problems start from it. Most people use poll(), but I don’t like it. Waiting is so much better and cooler and harder to deal with! I actually wrote it with poll() and found that the timeouts can’t really offer a good user experience, for example when the fd(file descriptor) is closed I want the GUI to display the status change almost at that moment. When it has to wait for the timeout to end doesn’t give the user correct idea of whats going on. So I needed reading procedure that blocked when the buffer is not filled and returned the filled count when the fd is closed or when the buffer is filled.

#include <unistd.h>
#include <errno.h>
#include "reader.h"

int reader_read(int fd, char *buffer){
    int rd = read(fd, buffer, READER_BUFFER_SIZE);
    if (rd==-1){
        if (errno == EINTR)
            return reader_read(fd, buffer);
        else
            return 0;
    }
    int buffer_wr=rd;

    while (buffer_wr < READER_BUFFER_SIZE && rd>0) {
        rd = read(fd, buffer + buffer_wr, READER_BUFFER_SIZE - buffer_wr);
        if (rd==-1){
            if (errno == EINTR)
                continue;
            else
                return 0;
        }
        buffer_wr += rd;
    }
    return buffer_wr;
}

This piece of code does exactly that, it blocks until the buffer is filled. Ahh the beauty of blocking! There’s nothing much to it, its just clumsy wrapper for read() but I hope this was included in POSIX. It makes life so easy! There’s another wrapper for a Linux kernel feature called inotify, I guess this is ‘inode notify’, which is what it actually does. It monitors files for change and sends data on a fd when its changed. But this is not whats useful, whats useful is if we can register a callback for the file modification. There are numerous libraries that do this, but hey whats more hardcore than directly by yourself. And since this is a hobby/educational project I went in that path, so I wrote up fsevents.c which makes a thread poll() for ever until the fd is written with the modification information, which is simple and effective.

That’s almost all the new stuff that are in this project. And these won’t be this much awesome if I used an easier language, and people who are concerned about system resource usage won’t use it for high resource usage. Qt and Netbeans played very well. Netbeans had a few problems here and there, like corrupting two of the source files good thing I had them pushed to github.com. This is my first of many things, the first actually usable C/C++ GUI, the first that’s designed for more than 2 threads(no semaphores or mutexes, all operate on their own data), and most importantly my first matured contribution to the community since this is all FOSS. I include matured since rsinglish was the first, and it is just a script. So I guess this is more mature, and I hope people won’t try to bite my head off for not using autotools. As I’ve mentioned earlier those tools are not that trivial for me, but I hope to make debs and rpms as soon as possible if anyone is experienced in such work, I’d appreciate some help! And lastly, its well worth mentioning axel, the awesome CLI downloader! The help received from guys at ##posix and #kernelnewbies is greatly appreciated.

https://github.com/madurax86/multi-axel

Advertisements

Multi-Axel a GUI front end for Multiple Axel processes

It’s still on heavy development at, https://github.com/manushanga/multi-axel. It is now only for Linux systems because I used inotify Linux kernel feature to check file changes without polling for them(which is faster and cooler!). You’ll need Qt development files to compile the project has both C and C++ this is my first project of such kind so do make comments/patches and inform me!