 So as that part of the slide says my name is Steve and as that part of the slide says I'm a geek as You can probably tell from my voice. My accent is English. I am a European despite what the government is saying so That joke doesn't work in the UK for some reason So if we're all in the right talk, this is about debuts asio Which means I'll start off by mentioning what debuts is what asio is and at which point you should be able to work How what debuts asio is all about I'll talk about the existing libraries that solve the same problem And then why we actually built the whole thing again So debuts is an inter-process tool you have a Debuss statement sits here that runs when the system starts You have an application that talks to the debuts library It serializes a function call to the library that debuts Damon then sends it off to another application And then the result is returned via debuts Damon to your application This example is the first one I always play with it allows me to control the screensaver Programmatically not big not clever, but it is kind of useful I know someone's got a chip in their arm that when they walk away from their machine It automatically locks the screensaver with this So that's debuts just communication nothing more asio is a library that does asynchronous communication Generally within sort of networks and things like that. So it's kind of useful for IO programming It's also part of boost but we'll come to that later So therefore Debuss asio is a library that allows you to serialize a function call that in communicates to the debuts Damon Before passing on to another application and as you can probably guess it already exists There are lots of libraries that do this But as always they're never quite what you need it doesn't quite match the use case So the question is well, what is our use case? So our use case are these things That's a bright sign player It's a bedded Linux box and it's used for media for playing video files HK HD 4k files that sort of thing Well, this is what we build and it's embedded Linux and it's got lots of processes and it therefore has to work multi-threaded a Lot of the library seem to have problems with threads. Not quite sure why We've got a million of these things in the field They're running 24 hours a day seven days a week Therefore if you only have a race condition in a multi-threaded application go one once every 10,000 hours normally on a desktop That's fine when you've got this many things. It's going to happen fairly regularly Except when you're actually trying to test to debug it It's also embedded. We've got 32 and 64 bit platforms We want as few dependencies as possible even though it is an embedded platform and it's quite a big platform We still don't want to bring in a whole load of libraries just to facilitate the communications It's why one of the things like qt bus was not available. We were trying to remove dependencies rather than put them back in And as I said, it's an embedded Linux box So we've got a whole load of open source software not that it's important for this But it is important for our license compatibility. So the license has to be good as well So you've got the standard three options you either take an existing project and work on that So you've got to talk to people in the project team You've got to learn the code base you fork it because you don't want to talk to the developers Or you just say no going from scratch I'm going to build this myself and it turned out that this was the option that we have to take So why we built it? Well, we started off Because we needed it. There's too many bugs coming at random points because of race conditions because of threading So we said right well, that's our use case And that's all we're gonna build nothing fancy nothing clever We're just doing the bare minimum we we need so which language should we use I? But go at the top because goes the one I kind of really wanted to use properly in anger Turns out no one else in the company does go and While for some people it's like this is a great career move This makes sure no one ever can ever replace me because I'm the only go person in the company Unfortunately when you take that approach you're the only go person in the company Which means you never get to do anything else or anything interesting you're stuck maintaining your own little projects So it's like not that it's gonna have to be C++ and we'll take version 14 We're not quite bleeding edge enough to ont 17 So 14 is a happy medium and not there's anything wrong with seed by the way I did start my career as a C programmer and there is nothing wrong with this code This is recently decent code it locks everything it unlocks everything it checks for null pointers coming back from memory allocation it unlocked But I don't want to do all of that when the language Will do all that for me fire exceptions and so forth. So it was almost a no-brainer at that point. It's C++ 14 We could have gone 11 And we might have picked up some legacy users who are on 11 code bases Unfortunately that would add to their tech debt as well as ours maintaining an older version of the spec So straightforward to version 14 Which a sync library did we use you already know that it's in the title. It's asio Chosen because it is actually fairly decent and it is by boost Boost has quite a good history of coming up with nice specifications that are taken by the C++ standard And then folded into the next version of the standard. So adopting things with boost seems to be a good win for future compatibilities Another design decision we had to make it's not about the bright sign even though this is a company project it's open source and We don't want to have any of the bright sign stuff in it These books have been made for the last 12 15 years or something like that Which means we've got a very good logging system, which I don't want to use We've got all this kind of streaming stuff. Don't want to use it Sockets code don't want to use any of that The simple reason if I'm saying we can't be using Qt bus or this D bus library because of it brings extra dependencies It would be rather hypocritical if I then started in throwing a whole load of dependencies from our existing code base So didn't do that But it turns out that writing little bits of logging and streaming code isn't actually that complex or takes any real time So two words on the API compatibility We didn't do any Who cares it's it's a new thing if you want to new use new clever C++ things You'll use the new API. So you'll have when you make a call to D bus and it goes through to another Application the result comes back you want it coming back in a callback But not the callback that was cool and trendy 20 years ago in C You want landers because they're new and cool So you're gonna have to use the new API anyway So we might as well make a clean break and not waste time back implementing old APIs So the methods we built it is simple you lock me in a room for three weeks and I churn out code. I Know this quotes about turns coffee into code. I turn beer into code. It works much better So the first step was pre-production. It's the same as you do in the film industry You start in the film industry draw a whole load of boards and you have a little pictures for every scene You're gonna have here. I read through the spec. It is quite long It isn't too dull, but I read through it a couple of times just so that in my head I could see things like oh if I build it this way I've suddenly realized the page 50 of the spec says this thing happens So therefore when I do this I don't do that. It's one of the few times I don't follow the agile approach of just build the very first bit So I know there'll be something later on to trip me up. I did a lot of stuff with D bus send So obviously D bus exists as a protocol and has existed for protocol for about 15 years So there are various tools like D bus send and defeat that I was able to use to look at how the methods were Serialized to the D bus Damon and how the results were serialized back from the other application Also, I use so cat for the first time I don't know if anyone has played with that at time. It is it is what the name says it's a socket concatenation thing and you can just look at all the bites Flowing through from the D bus Damon to your application and back again This was an absolute godsend because by doing this I could look at all the data going forward It's like well spec says it's this I might have interpreting that spec correctly I look at the bytes coming through so cat and yes, I am which was a very good time saver So first things first I built an MVP that did nothing but say hello to the Damon This isn't me trying to be clever the very first thing you have to send to the D bus Damon as an application That wishes to use D bus is the word hello if you don't say hello It will throw you off it will close the socket and say bye-bye be more polite next time So I wrote a thing that said hello to the Damon I sent the messages that I'd already grabbed from so cat and I just sent them as big binary blobs and it worked I thought great. I then started building up that binary blob Programmatically saying I know what this calls. This is calling a lock command to the screensaver I'm gonna then program this in and I've written that so I could write a line of code That would lock the screensaver in my world That was really great. I then delete. Oh, yeah, I did tests if the boss asks I did tests What I then did is I deleted all of this and I started again Why well you just do you learn various things about getting stuff up and you think there's a few bits of crafty rubbish in here I don't want that going out. So I'll start again knowing what I know now. I can do a better version next time So the guy think the code is a lot better It also means when the boss saw my very first implementation. It was actually my second Which means they now think I'm slightly better than I really am Well, I started building it for real I started with threads I knew we had to do threads threads was one of the driving factors to this So I made sure that the threads were in there at the very first first day of coding It helps because it means they're gonna get tested for the longest and I know that's where problems are gonna come in So started everything with threads. It's the same as if you do security You don't add security as a feature at the end of the product unless you're doing IOT stuff I guess but it's meant to be there at the ground level. Everything is based on security. Everything here was based on the threads. I Use callbacks with landers because I like landers And it's easier to send data than it is to receive That might sound kind of obvious if you've spoken of a foreign language You'll realize that it's much easier to power repeat something the teacher has told you then actually understand what someone is saying With the reading of data, it's really really difficult because we're dealing with serial data here and Zero data as we know is what book book? unfortunately If you've if you're pushing some serial data out and you make a mistake You're not going to realize until it actually crashes There's no real security or protection for you reading too many or too few bytes of serial data So you get the first message in you then get the second message which you've badly passed You then get the third message which says I've got a string which is four billion characters long and then your program stops here Not here where the error occurred So there was a lot of things you have to do there and the simple data types point It's because D bus allows you to send integers and strings and arrays Because it's serial you can't just jump over a block you don't understand So you have to get a lot of things in place before you can even run the simplest of tests when it comes to reading the data in The problems as we say the serial protocol they put padding on the spec which is great We like padding it means it's nice and fast when it gets into CPU land But there was always the question of if I've got a string that is zero bytes Does this mean I now because it's already padded to four bytes if the string is zero it's already aligned So does that mean I add zero bytes of padding or four bytes of padding? And I found that out, but the hard way by trial and error It also means you there's various other side issues where you're trying to do padding and he's like well I've got three bytes. I've got to get the next one in as padding Variable data types Yeah, the fun thing with C++ being a strongly type language is when you've got a protocol such as this which supports any data types You can't just say well, I'll I'll cast it to a void pointer and then I'll just do something clever later on So I discovered the thing in boost called boost any which essentially allows you to do data types as a union So the same variable can be a string or an integer or Array for that matter and going back to what I said earlier things in boost tend to find their way into the standard Halfway between writing the first line of this talk and the last line of this talk turns out boost any is already in the standard It's in the 17 version. So again, it was a good choice to make these sort of things future compatible And here is an example of the code running. It's pretty simple. You open up a socket to the D bus statement of fire run You do your basic authentication, which is the only one that's ever really supported You make the hello. I'm here method call and then you just Hook on to the network Marshaling is what they call serialization So when you have a method call that you serialize the center the D bus statement in D bus world That's cause that marshaling and un-martialing Schedule wise it took me four weeks. I said three weeks earlier That was three weeks of work one week of meetings emails stated reports all that sort of you know These is going for lunch all the auxiliary things you have to do to support yourself as a developer Probably around six weeks of reviewing casually here and there Excuse me. This is the practical reason Much nicer than water As you can see from the last joke far too long working out the names I wanted to call it depot Because then it would be D bus depot But judging from your reaction. It was probably right not to call it that So we went with D bus as a oh as sort of a mindshader say we have as a oh here so conclusions Sometimes you do actually have to rewrite things. It's not very open-sourced We we don't need or should be rewriting reinventing the wheel every time but every now and again You get to the point of well, we just have to it is going to be quicker and more effective in the long run We had a lot of good solid use cases Because we've got the players we know what we're going to be sending as far as the bus messages go We chose the proper language Step by step debugging comes first so whenever I write code. I never run it I just step through it in the debugger to make sure it's doing what I think it's actually meant to be doing It takes a little longer to get to the first version but when you get to that first you think I'm pretty sure this is right and Writing protocols is easier than reading them. So that's it I'm a I've got 12 questions seconds for questions, and I'm just gonna update my scorecard. There we go 19 false stems Makes me feel old but thank you five second question a Four seconds a three second question. You've got two seconds to answer a question any Yeah, I'll be outside so if anyone's got any questions call me then so thank you