TCP C++ server upgrades

A quick snippet from tonight’s diary entry:

20:30 – I’m still reading up on some stuff about non-blocking TCP server programming and so far the best examples come from http://developerweb.net/viewtopic.php?id=2933. Ideally what I want is NOT to have a shed load of threads running, which I’ll be using a thread manager for, but a way of quickly determining if a connection is valid before shutting it down.

By the looks of the examples,  a continuous loop could be checking upto 1024 connections at any time before sending them off to another thread. This method has caught my attention big time because I should be able to setup some kind of timeout very quickly to close the connection if it doesn’t respond to the initial connection request. And I can still serve 100 to 1000 devices without any problems at all.

The same single thread can be constantly checking for connections and readability. It’s the readability part that matters the most here because it will be timed very precisely. Once a connection passes the readability test by passing the initial CSPRNG test, then it can go to a thread handler. Otherwise it gets closed. All of this a single core/thread can easily handle.

I will be studying this a lot further as this looks to be the way forward for a tcp server.

And this is just from my crappy laptop at home.

Basically, the new software upgrades to the server will be 1000 times more efficient than the current Java version. Although once in the cloud, the Java version can easily serve over 500 devices because of the bandwidth increase.

The updated C++ version will increase that significantly as well as handle dodgy connections better. Once a connection has passed the CSPRNG test then the TIMEOUT increases a smidgen.

I’ve already got the CSPRNG functions running and tested and written in assembler code to reduce that bottleneck too.

Until next time… WLGfx…

Linux Thunar file manager

With all the faffing about lately with assembler at home, I remembered how easy things were when I had my Amiga 1200. On the Amiga, I used to use Directory Opus which allowed me to customise such things as compiling assembler and C files.

Image result for amiga directory opus

All those empty boxes could be custom build commands, archiving, running my own scipts, etc. Even the ones that are in the screen shot could be removed and changed for something else which I did at the time. Creating software using Directory Opus was a doddle.

I needed something exactly like those old days now. Actually I should’ve looked for this a long time ago.

I found Thunar file manager. I’ve just tested it out with a simple GCC compiling a C program and making an executable. How simple it was makes this awesome.

Image result for thunar file manager custom commands

I’m hoping I can add my custom commands to keyboard shortcuts and also group them. Apart from that it looks just like any other file manager. All I need to do is to right click or do a keyboard shortcut and any of my custom actions can be done instantly. This will make life so much easier from now on.

eg… Compile a C/C++ program and create an executable:

x86_64 assembler first steps function parameters

Okay, so far I’ve figured that there are six registers used for the first 6 parameters used in a function call. The below c program sets up the function which also uses RAX as the return value:

#include 
#include 

int asmparams(int, int, int, int, int, int);

int main(void) {
	int ret = asmparams(1, 2, 3, 4, 5, 6);
	printf("return:%d\n", ret);

	return EXIT_SUCCESS;
}

This now expects my assembler function to take 6 arguments and a return value. Below is how those first 6 arguments are used in 64 bit Unix function calls to assembler.

		section	.text

global	asmparams:function

extern	printf

printnum:
		push    rbp                             ; stack frame? x64

		push	rsi
		push	rdx
		push	rcx
		push	r8
		push	r9

        mov     rsi,rax
        mov     rdi,pf_msg 
        xor     rax,rax     
        call    printf  

        pop		r9
        pop		r8
        pop		rcx
        pop		rdx
        pop		rsi

        pop     rbp                             ; stack frame

        ret

asmparams:
		mov		rax, rdi
		call	printnum

		mov		rax, rsi
		call	printnum

		mov		rax, rdx
		call	printnum

		mov		rax, rcx
		call 	printnum

		mov		rax, r8
		call	printnum

		mov		rax, r9
		call	printnum

		mov		rax, -1		; return value
		ret

		section	.data

pf_msg	db		"%08x",10,0

When I’ve got some time to explore how the ‘Prologue’ and ‘Epilogue’, or beginning and ending of a function, I post about that. At least now parameters can be passed to assembler functions.

Things have changed a lot since the 680×0 days. Then you could use a single push/pop instruction to push/pop multiple registers.

Eclipse Oxygen and NASM

Tonight I set myself a mission of getting any IDE to build assembler files alongside my C/C++ code.

Find it here: Eclipse Oxygen and NASM

I tried NetBeans at first but the IDE isn’t good at all, actually quite useless for setting up NASM. I spent about half an hour trying this out and eventually gave up. Apparently there are plugins out there, but I wasn’t going to try them out as they were not part of the NetBeans official plugins.

So I look into Eclipse and initially I was put off because there was nothing in the official plugins. A few searches later and I got it. It was already built in to the CDT plugin for eclipse. I only had to make a minor alteration to get it working.

Now I can have a C/C++ project that will also automatically compile and link my assembler source files.

Here’s me thinking I was going to be stuck over the weekend finding this out. Took an hour. What’s next to move on to? Oh yeah, my project. he he…

Libvlc and my Odroid

Before I go ahead and actually buy the Odroid C2, I thought I’d dig out my U3 and try the vlc library on that. All I had to do was to copy the project folder over SSH to it and build it. At first it didn’t compile because I needed to install the X11 dev files, and then again I had to install the libvlc-dev files. And then it built just fine.

Major problem though, VLC doesn’t have hardware acceleration on any of the Arm processors yet.

Well, now it looks like I’ll either go down the Qt route, FFMpeg route, OGV decoder route, or find another player library.

One thing I do know is that I’d like to stick to a single video format, ie OGV. So that makes writing my own player easy enough.

My next step is to get a player working by myself and make it work on the Odroid. I’m going to see about the OGV sources before checking out other open source players.

I’ll keep you posted.

 

Fullscreen video playlist done

Using Linux and libvlc I’ve finally got what I was aiming for. A full screen video playlist player. And it was quite easy.

The steps to get here:

  1. Monday: Play a media file. A few lines of code did this. And with the addition of one extra line of code made it full screen.
  2. Play a playlist of videos full screen. This is where things went wrong. After one video had finished, the vlc player would quit fullscreen, flash the desktop and then play the next video in full screen. This was not acceptable.
  3. Tuesday: Using the stock Linux libraries to go full screen. This took all of about 20 minutes from start to end. And again, in just a few lines of code. It was a chaotic night at home so I just finished up there.
  4. Wednesday: Just chilled out and watched TV after work instead.
  5. Thursday: I now needed to use the full screen window and attach the videos to it so that the desktop doesn’t appear. By just passing the window ID to the vlc media player, this was done.

Now all I need to work on the managing the playlists over the internet. And order myself and Odroid C2 with a few other gadgets. So far, this is going 100% perfectly.

By my reckoning, I should have a media player that boots up in less than 10 seconds and playing. How awesome…

The hefty part of the coding is about to start…

Linux X11 full screen

Wow! Just how easy was it to have a full screen window in Linux?

In windows, you had to include a shed load of libraries and link to them. In Linux you just link to X11, one or two parameters, and that’s it.

All I required was a basic window that I could attach the VLC player to, similar to any 3D API requirements, so that I could bypass VLC switching from full screen to desktop all the time. And all in 20 lines of code, not obfuscated, and one instruction per line, with a while loop for a pause, I got it. Windows couldn’t do that. It would take, erm, lots of, erm, junk to do it. erm 😉

Again, not a lot of time tonight to do stuff, so by the time I came round to getting this done, I thought I might as well set a target for this step to be done by tomorrow night. Now it looks like tomorrow night I can attach VLC to play a playlist.

See what happens tomorrow if chaos don’t arise.

libVLC and fullscreen

Okay, so I was successful with getting libVLC to play a video in full screen in just a few lines of code. This was a great success. However, when using a play list, each item is shown in a window.

Tonight I haven’t the time to set up a full screen window and attach libVLC to it, so I will try that tomorrow. There’s tons of Linux windowing API’s I can use. Just a standard X11 window will be fine as there will be no user input at all.

It’s no use having a black background as a desktop as some videos will end with a different coloured background.

Ah well. Plod on tomorrow. Almost there.

If I fail then it will be a minimal build of ffmpeg or maybe just the OGV libraries and I will write a player myself which will take a tad longer than I wanted.

Sample C code on Linux:

#include <X11/X.h>
#include <X11/Xlib.h>
#include <strings.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

extern "C" {
#include <vlc/vlc.h>
}

const char *files[] = {
	"/media/wlgfx/WLGfx/WLGfxMedia/2017July/WLGfxJul/wlgfx.ogv",
	"/media/wlgfx/WLGfx/WLGfxMedia/2017July/sample1/sample.ogv"
};
const int files_count = 2;

void play_media(libvlc_instance_t *inst, const char *uri, uint32_t win) {
	libvlc_media_t *m = libvlc_media_new_path(inst, uri);
	libvlc_media_player_t *mp = libvlc_media_player_new_from_media(m);
	libvlc_set_fullscreen(mp, 1);
	libvlc_media_player_set_xwindow(mp, win);
	libvlc_media_player_play(mp);
	sleep(1); // enough time to start
	while (libvlc_media_get_state(m) == libvlc_Playing) usleep(200);
	libvlc_media_release(m);
	libvlc_media_player_release(mp);
}

int main() {
	Display* dis = XOpenDisplay(NULL);
	Window win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 0, 0, 10, 10,
			0, BlackPixel (dis, 0), BlackPixel(dis, 0));

	Screen *screen; // get screen size
	screen = ScreenOfDisplay(dis, 0);
	int dwid = screen->width;
	int dhgt = screen->height;

	Window root; // position mouse to bottom left (hide it)
	root = XRootWindow(dis, 0);
	XSelectInput(dis, root, KeyReleaseMask);
	XWarpPointer(dis, None, root, 0, 0, 0, 0, dwid, dhgt);
	XFlush(dis);

	XInitThreads();

	Atom wm_state = XInternAtom(dis, "_NET_WM_STATE", False);
	Atom fullscreen = XInternAtom(dis, "_NET_WM_STATE_FULLSCREEN", False);

	XEvent xev;
	memset(&xev, 0, sizeof(xev));
	xev.type = ClientMessage;
	xev.xclient.window = win;
	xev.xclient.message_type = wm_state;
	xev.xclient.format = 32;
	xev.xclient.data.l[0] = 1;
	xev.xclient.data.l[1] = fullscreen;
	xev.xclient.data.l[2] = 0;

	XMapWindow(dis, win);

	XSendEvent (dis, DefaultRootWindow(dis), False,
		SubstructureRedirectMask | SubstructureNotifyMask, &xev);

	XFlush(dis);

	printf("XWindow initialised with threading enabled\n");

	libvlc_instance_t *vlc_instance = libvlc_new(0, NULL);

	printf("Playing media files in vlc attached to window\n");

	uint32_t id = (uint32_t) win;

	play_media(vlc_instance, files[0], id);
	play_media(vlc_instance, files[1], id);
	play_media(vlc_instance, files[0], id);
	play_media(vlc_instance, files[1], id);

	libvlc_release(vlc_instance);

	printf("Hopefully all was successful\n");

	return 0;
}