text:
Parsing JSON
There are many libraries out there to parse JSON files. It might be a futile attempt, then, to write yet another one. However, when you're working on a RTOS where memory is golden, and the alternatives don't look that great, you got to do something about it.
Recently I wrote a JSON parser for a project at work. This parser uses constant memory, regardless of the amount of data it's working with, and deserializes directly to a C struct. Similar, in spirit, to the JSON parser that's part of the Golang standard library, that encodes and decodes data based on a tagged structure.
The lexer is the usual state machine, where the state itself is a function pointer to a function that handles that particular state.
I've been using this technique for a while, and I found that it's a very clean and efficient way of describing state machines, specially for lexers.
I began using it after a coworker wrote a parser for a DSL using it – and he got the idea from the – you guessed – Golang template package. (There's a nice talk by Rob Pike about it – I recommend this talk not only for the lexing goodness, but also for the tips on how to evolve a concurrent design.)
The parser implementation itself is nothing to write home about. However, by using the same idea used in Lwan's mustache template engine to obtain the variables, it manages to do some things that are not common in JSON parsers written in C:
- It will accept only values of known types for a particular key.
- It will save the decoded value directly in a struct field.
- It won't try to decode the same field twice.
The first point is crucial when working with data received from the network, which is precisely the kind of thing I'm dealing with. This avoids problems such as type confusion and such, and moves the responsibility of checking the types to the library rather than the user of the library.
By saving the decoded value directly into a struct field, it does use a predictable amount of memory. This is good, as it's not going to balloon out of control, or require some guesswork to know beforehand how many tokens are going to be necessary to deserialize some values. The C compiler already knows exactly how many bytes a struct needs.
Some fields might be optional in a JSON blob. So the parser uses a bitmask to mark which fields have been decoded (and returns that, so that the library user can efficiently test if a value has been deserialized or not). Since it was easy to do, the library refuses to decode a key that has been deserialized before.
So, a typical use is the following:
/* First, define a struct to hold the values. */
struct values {
char *some_string;
int some_int;
bool some_bool;
/* Then, define a descriptor for that struct. */
static const struct json_descr values_descr[] = {
FIELD(struct values, some_string, JSON_TOK_STRING),
FIELD(struct values, some_int, JSON_TOK_NUMBER),
FIELD(struct values, some_bool, JSON_TOK_TRUE),
/* (FIELD is just a macro that saves the offsetof()
* each struct member so that a pointer can be produced
* afterwards.) */
/* It's now just a matter of parsing the JSON now. */
struct values values;
int32_t ret = json_parse(serialized, strlen(serialized),
values_descr, ARRAY_SIZE(values_descr), &values);
/* Bits 0, 1, and 2 of ret will be set if some_string,
* some_int, and some_bool have been successfully
* deserialized. */
Another thing that could be done – but that has not been implemented yet, is to do the opposite as well: the descriptor and a struct to produce JSON-encoded data. This has many advantages over the usual JSON libraries that require generating a JSON tree in memory just to serialize it afterwards.
And although I'm quite happy with this code, there are still some limitations that I'll address whenever I have the need.
Mainly, there's no way to parse nested objects or arrays. I've written code to do this but these changes haven't gotten any fuzz-testing action so I'm holding them off it until my living room heater^Wcomputer has worked on the problem for at least a week.
Another one that's not a deal breaker for an embedded OS is the lack of floating pointing numbers (only integers for now). Parsing floating point is trickier than it sounds, and there's no strtod() in Zephyr's minimal libc.
As a minor issue to work around, there's the return value: this limits the number of fields to be parsed to 32; that should be plenty for most uses. However, in the unlikely event that's not sufficient, this can be worked around by having multiple descriptors.
And, finally, there's the JSON encoding part that I've mentioned already.
The major problem with this piece of code, that can't be fixed by writing more code, is that I can't use it with Lwan due to licensing reasons: although it is open source, part of the Zephyr project, it is licensed under the Apache 2 license, which is incompatible with the GPL2+ used by Lwan (would have to bump it to [L]GPL3).
(For those that might ask how fast is it: it's fast enough. I didn't measure, I didn't compare, and I don't really care: it's readable, maintainable, and does the job.)
Infect to Protect
I'm not one to jump on each and every bandwagon I see. Sometimes that's a good decision, sometimes it's better to just wait and see where they go before taking any action.
Containers are one of those ideas that, while promising and intriguing, were quite clumsy in the beginning, so I ignored them for a good while. It's sufficiently mature now; so much so that's quite difficult to ignore them. Time to investigate them again.
Now, most of my work revolve around writing embedded software that runs on bare metal; containers don't really solve any work-related problem I have. For personal usage, package management is more than sufficient to install programs. However, the sandbox aspect of containers are quite interesting and it's something I'd like to know more about.
There are many articles around the web explaining how containers on Linux work. Some get out of their way to explain in depth all the machinery necessary to make them work, so there's no need to repeat it here.
But, in sum: almost all of the kernel side of things was already present before containers were actually a thing: cgroups, system call filters, etc. Containers (and their runtimes) only make them so simple to use it's transparent for the user.
I usually have a hard time understanding things that I cannot build, so I decided to build a toy container runtime. It's crude and it's a far cry from what any industrial-strength container runtime is capable of, but it's not only a start, it's implemented in a way that makes things a lot easier for the user.
Virulent tutorials
Before I go into details on how my contraption works, a little bit of background. I've been using Linux for over 18 years, and began my forays in C about 14 years ago.
Around that time, a pretty interesting HOWTO explaining how to create viruses for ELF binaries came out. It explained not only various methods of infecting an ELF executable, but also methods to detect them. Suffice to say, I couldn't understand a thing back then. A few months ago, though, a conversation in the local hackerspace brought up that tutorial; I could now finally not only understand the techniques but put them to use.
One of the techniques explained in the HOWTO involves finding some unused space in an ELF segment that's also executable, writing shellcode to that area, rewiring the executable's entry point to point to the shell code, and modifying the shell code so that it points to the original entry point. It's all quite Rube Goldberg-ey, but it's actually quite simple.
This way, a chunk of code can be executed every time that program starts, without altering the size of the program. The perfect crime.
Dual use technology
By now, you've most likely connected the dots: the idea is to use the very same technique, originally designed for viruses, to create a program that transforms any program into a sandboxed version of itself.
The prototype I wrote is very elementary; the only thing it does is limiting, just once, which system calls a program can execute.
Sort of a less-powerful version of OpenBSD's pledge(2) (née tame(2)), which can be repeatedly called to reduce the amount of privileges a process has. Useful, for instance, in cases where a configuration file has to be read before processing user-supplied work. That BSD version has been sprinkling calls to pledge() in almost all of the programs in the base install (which is easier for a BSD system, since everything is kept under the same roof.)
But, unlike pledge(2), this thing can be applied to binaries that have been already built. No source code modifications are necessary. If your distribution can withstand the stench, "infected" binaries could be a thing in the default installation.
Filtering the system calls
Any respectable container runtime will perform a lot of tasks to sandbox a process and their children. So, for a proof of concept, I decided to do just the bare minimum: limit system calls using Seccomp-BPF.
Seccomp is a set of features present in the Linux kernel, since the 2.6.x days, that allows restricting what a program can do, system call-wise. The original intent was to do not permit any other system calls excepting those to end the program, and read and write to already-opened file descriptors. In some scenarios, this is perfectly acceptable. For others, there's the seccomp-BPF extension.
BPF stands for Berkeley Packet Filter. A famous use of BPFs is in the tcpdump program, where rules such as "only give me back TCP fragments with the RST flag set" can be passed to the kernel; packets that don't match the filter are not copied back to the userland, reducing a lot of the chatter between the two lands.
Obviously, this must be extremely performant, since kernel time must be conserved at all costs (the kernel is there only to serve userland, after all). Linux has many ways to speed up BPF programs, including an in-kernel JIT compiler. Some restrictions are in place that wouldn't allow BPF programs to take an infinite amount of time to execute, and this blog post is a good introductory reading material on the subject.
Another, slightly less famous use of BPFs is with the seccomp-BPF extension. Instead of filtering network packets, processes can, for instance, pick which system calls they're allowed to perform. And that's precisely what's necessary for my proof of concept.
Scripting like a kid
There are many ways to skin a cat. I decided to take a look how other programs were doing their sandboxes, and eventually found one that seemed easy enough to copy the technique from.
Unfortunately, writing shellcodes in C isn't that easy, specially if you don't know which C library a program was linked with (or if it were linked to a C library in the first place). Luckily, all the shellcode has to do is make two system calls, which is straightforward to do with a little bit of assembly.
The first call will forbid the process from getting more privileges. The second call will actually copy the BPF program to the kernel side.
The first call is painless: just set a few registers, invoke the syscall, done.
The other one takes a little bit more work. A few things helped: I've used nasm, which is a macro assembler, and wrote a few macros that let me write BPF programs as if they were standard x86-64 instructions.
The remaining issue is that a pointer to the BPF program must be passed to the call to prctl(), and the shellcode must be relocatable. A common trick to perform in these scenarios is to employ the fact that, on x86, when a call instruction is made, the return address (i.e. the address of the byte right after the call instruction) is pushed to the stack:
; …
jmp push_bpf_addr
pop rdx ; rdx points to the BPF program
; …
call apply_filter
bpf_stmt ; …
bpf_jump ; …
sc_allow ; …
; …
The bpf label doesn't point to any x86 instruction: it contains only macros that expands to the definitions of struct sock_filter as defined in linux/filter.h. To copy the BPF program to the kernel, the prctl() call expects a struct sock_fprog, which contains the BPF program length (in number of struct sock_filter elements), and a pointer to the base of that array. Since there's no way to know where this code is gong to land in memory beforehand, this trick comes in handy: after the call apply_filter instruction, the top of the stack now contains the base address of that array.
Now that I had a way to write the shellcode, it was just the matter of shoehorning it into the executable.
Scoring a goal
For the proof of concept, I was initially going to write the infection program in Python, as I usually do for throwaway code. However, I wasn't successful in finding a working ELF library that would let me dump the modified executable.
I was too lazy to actually fix or write support for that, so I kept looking for alternatives and ended up finding the ELFkickers suite from the always excellent Muppet Labs. It includes an "infect" program that does exactly what says in the tin: it takes in an executable file, and produces another executable file that creates a setuid shell before continuing to the original program. Exactly what one would expect from a program with nefarious purposes.
So I substituted the original shellcode for the one I've just assembled, and now I had a proof of concept. Which of course didn't work the first few tries. In fact, it took a long while to get it right.
Debugging the contraption with gdb
The GNU Debugger is indeed very powerful, but ease of use (compared to the Turbo Debugger I used to use in the DOS days) is not it's strong suit. I'm not used to using it to debug programs without access to source, and this was a good opportunity to learn a few things.
Since the infection program modifies the ELF entry point, setting a breakpoint on main() won't actually work. But this is easily solvable: just use readelf(1) to find where the new entry point is, and set a breakpoint to that:
$ gcc -o hello hello.c
$ readelf -h hello | grep Entry
Entry point address: 0x400490
$ ./infect hello
$ readelf -h hello | grep Entry
Entry point address: 0x4007bc
$ gdb ./hello
(gdb) break *0x4007bc
Breakpoint 1 at 0x4007bc
From now on, it's just the usual execute-inspect-modify-reassemble-reinfect loop until it works. Although it's no td, I'm certainly glad GDB has layouts that displays both the disassembly and the registers.
Watching the magic happen
The hello program is very short and the call to socket(2) doesn't make much sense there. It's just a way to test what's going to happen when the filter is in place, without the need to modify the program to test this assumption. (Lots of things happens when executing a simple program such as this.)
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
if (argc < 2) {
printf("no socket created\n");
} else {
int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("created socket, fd=%d\n", fd);
return 0;
Executing the program before infecting it gives the following output, as expected:
$ ./hello
no socket created
$ ./hello 1
created socket, fd = 3
Indeed, if the program is executed under strace, it all goes exactly like it's supposed to be:
$ strace ./hello
execve("./hello", ["./hello"], [/* 58 vars */]) = 0
write(1, "no socket created\n", 18no socket created
) = 18
exit_group(0) = ?
+++ exited with 0 +++
And, with a command-line argument, so the socket is created:
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
write(1, "created socket, fd = 3\n", 23created socket, fd = 3
) = 23
exit_group(0) = ?
+++ exited with 0 +++
However, the magic happens after the "infected" binary is executed. First, without creating a socket:
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, {len=30, filter=0x400824}) = 0
write(1, "no socket created\n", 18no socket created
) = 18
exit_group(0) = ?
+++ exited with 0 +++
Notice the calls to prctl(), very similar to the ones found in the previously-mentioned commit. And then the program executes as usual. Now, if an argument is passed, the program will attempt to create a socket:
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, {len=30, filter=0x400824}) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 41
--- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0x7f2d01aa19e7, si_syscall=__NR_socket, si_arch=AUDIT_ARCH_X86_64} ---
+++ killed by SIGSYS (core dumped) +++
[1] 27536 invalid system call (core dumped) strace ./hello 1
And Seccomp kicks in and kills the program with a SIGSYS signal. As expected. It's alive!
Next steps
The prototype works. But there are a few things that must be considered before even considering this idea for anything.
System call whitelist
The list of system calls is still hardcoded within the shellcode. That's not optimal. Maintaining a list such as this for each and every program will most likely be so boring nobody is going to do that.
I can think of three possible ways of coming up with this list.
The first would be doing the same thing pledge(2) does: allowing a very restrict set of system calls at first, with some limitations, and then providing a few sets of calls per set of features a program might use: stdio, inet, tty, etc. The nice thing about this is that the filters are more fine grained; it's not just a whitelist of system calls. (The man page has more details.)
The second way would involve running the program under strace(1) and record which system calls the program makes from a few runs. If the test coverage for each run is sufficiently high, this will work very reliably; this isn't always the case, so the mileage may vary. Also, for certain large, complicated programs, stracing it all automatically could prove to be a challenge.
Another way would be the following: Grab a list of undefined symbols a program uses, and find them in the shared libraries it links to. Then scan the executable and the libraries for sequences like mov eax, 57; syscall (for the oldschool fork(2) syscall on x86-64) or mov rdi, 57; call syscall@plt. This is still not foolproof, since not necessarily a system call number (loaded into eax) will be hardcoded within a program or shared library.
There's a fourth idea, as well, which involves both doing the automated static analysis on the binary and running strace to catch "runaway" syscalls. This can get quite complicated and it's unlikely I'll get it correct in the first few tries (and, yet, the same shortcomings will apply in the end.)
For me, though, these experiments are all about the hunt, not about the treasure. So the tried and true approach that pledge(2) uses won't be used at first.
Filter optimization
Another thing that might be a problem is: on x86-64, Linux has hundreds of system calls. (329 according to sys/syscall.h at the moment I write this.)
Even if the JIT for BPFs is quite efficient, doing a linear search before each and every system call will certainly be a bottleneck. Also, BPF programs are limited in size, and a large whitelist that's implemented the same way as the prototype will limit the possibility for more fine-grained filters. Things like "the socket(2) call is allowed only for UNIX-domain sockets", rather than allowing whatever call to socket(2) would be impractical.
Since each syscall is identified by a number, a simple bitmap could be used to implement the whitelist. This will also free up some space in the BPF program for more detailed whitelisting for certain syscalls (for instance, only allowing certain family of sockets to be created).
After a quick read of networking/filter.txt, this seems doable by using an algorithm such as this, which will reduce the number of comparisons as the number of acceptable system calls increases:
if syscall_number < 32:
if bitmask_0 & 1<<syscall_number: goto accept
if syscall_number < 64:
syscall_number -= 32
if bitmask_1 & 1<<syscall_number: goto accept
if syscall_number < 96:
syscall_number -= 64
if bitmask_2 & 1<<syscall_number: goto accept
if syscall_number < 352:
syscall_number -= 320
if bitmask_10 & 1<<syscall_number: goto accept
return SECCOMP_RET_KILL
return SECCOMP_RET_ACCEPT
(Some of the if syscall_number < N blocks could be changed to syscall_number -= M if their respective bitmask is 0.)
Or maybe just a bloom filter instead of a series of bitmaps. I'll have to experiment.
Getting a larger vessel
Containers, of course, are not just about restricting which system calls a program is allowed to perform. There are many things that can and must be considered before even calling this a container runtime, or really consider that this is in fact sandboxing anything. Learning about namespaces, cgroups and virtual machines are certainly on the list of things to learn about.
While the prototype I built isn't practical and is of very limited use, I find the idea of sandboxed programs without the need for specialized runtimes very enticing.
Programs can be still packaged the way they have been packaged in the past decades, without throwing away some of the sandboxing benefits that containers provide, all the while not introducing new concepts for users.
Of course, something like this – even if properly implemented – won't be a replacement for containers. Specially if one considers their role as packets ready for deployment, which have a lot of value for devops personnel.
The code, as usual, is open source, and available from this Git repository.
Initializing a heap-allocated structure in C
A pretty common mistake that happens when programming things in C is to allocate less memory than necessary to hold a structure:
struct foobar *foobar = malloc(sizeof(struct foobaz));
Note that struct foobaz is passed instead of struct foobar. We might get lucky, and sizeof(struct foobaz) might be larger or equal than sizeof(struct foobar), but we might not.
There are lots of tools out there that will catch these mistakes: static analyzers such as the one from Clang, and Memcheck from Valgrind are just two examples that should be in any C programmer's toolbelt.
Even then, people often resort to a a nicer idiom: sizeof(*foobar), which not only avoids these problems, but also is somewhat future-proof, should the type of foobar change:
struct foobar *foobar = malloc(sizeof(*foobar));
However, structures often have members that, if someone forgets to initialize, will inflict some undefined behavior pains on the user. The things in the toolbelt might help here, as well as the calloc() function, that, in addition to allocating memory, also zero-out the memory block:
struct foobar *foobar = calloc(1, sizeof(*foobar));
Not always one would want to zero out the whole memory chunk just to fill out important fields afterwards, though.
Here's a trick that's being used in a yet-to-be-released project I've been working on and off for the past few months. It starts by defining the generic-chunk-of-memory equivalent of strdup(), memdup():
void *memdup(const void *src, size_t sz) {
void *mem = malloc(sz);
return mem ? memcpy(mem, src, sz) : NULL;
Then a macro is defined:
#define ALLOC_INIT(type, ...) \
(type *)memdup((type[]){ __VA_ARGS__ }, sizeof(type))
Then it is used like so:
struct foobar *foobar = ALLOC_INIT(struct foobar, {
.field = value,
.other_field = other_value,
.yet_another_field = yet_another_value
The compiler will check if field, other_field, and yet_another_field are actually part of struct foobar, and will abort compilation of a field isn't there or is of the wrong type.
The cast prevents the allocated memory block from being assigned to the wrong type. (C will happily cast any void* to any other pointer.)
The amount of memory allocated will be exactly what's needed by the structure, and all fields that not mentioned will be initialized with their default values as per designated initializer rules.
If memdup() is inlined, a good compiler will generate pretty good code, that's often byte-by-byte equivalent to allocating directly with malloc(), initializing all the fields by hand, etc.
If GCC is being used, the __auto_type extension can be used, to avoid having to type struct foobar twice. This has been suggested by Thiago Macieira. I'd use this sparingly, though.
__auto_type foobar = ALLOC_INIT(struct foobar, {
.field = value,
.other_field = other_value,
.yet_another_field = yet_another_value
It's a pretty nice idiom that I haven't seen anywhere else, and I'm blogging here as the project I'm working on might not ever see the light of day and it would be a shame if at least this didn't become public.
Hybrid C/Pascal Strings
I've been thinking for a while on how to reduce the overhead in Lwan's string buffer, when the strings are small. There are a number of ways of accomplishing this.
A somewhat common way is what std::string does: it reuses the bits reserved for effective string length, allocated buffer size, and pointer to buffer to store the string contents inline.
A clever improvement is, when the string is small, to turn the effective string length counter to a bytes remaining counter, and put it after the buffer that's storing the string; this way, when the string is at full capacity, this serves as a \0 terminator, which is very useful for compatibility with C. And, of course, as a result, one more byte can be stored in that string.
Another common approach are the strings used in Pascal, where the first byte tells the length of the string. This has the advantage of allowing strings to contain \0, but the disadvantage of limiting the maximum size of the string. If someone were to implement this in C, the advantage would turn into a disadvantage, as most string-handling routines present in the standard library would be then rendered useless.
Or would it?
I'm sure I'm not the first person to come up with the idea of having a C/Pascal String hybrid. But at least the Wikipedia article on Strings doesn't seem to mention this variant I just came up with:
- Keep the \0 to terminate the string. This helps reusing the string handling routines from the C standard library, which are usually very fast, hand-tuned functions
- The first byte tells the size, not in bytes, but in 8-byte blocks. To calculate the string length, one just jumps that amount of 8-byte blocks and find the position of the \0 terminator.
- Larger blocks could be considered if SIMD instructions were available.
With 8-byte blocks, this can yield strings up to 2KiB of size (256 * 8), with an overhead of only two bytes, while retaining compatibility with C strings. With SIMD, the maximum string size could be easily doubled or quadrupled.
Of course, this isn't actually an improvement on the kind of small string optimization performed by std::string, so I'm not yet convinced this is the way to go. This is one of the reasons I haven't yet implemented this, but I might use the fact that I'm currently enjoying some vacation time and write a prototype.
Life of a HTTP request, as seen by my toy web server
When learning a new programming language, I tend to write two things with it: a language interpreter (usually a FORTH-like language or Brainfuck if I'm feeling lazy), and a HTTP server. Sometimes, just as a challenge or a way to quench my boredom, I do this even though I've been working with a particular language for some time, as is the case with C.
None of these projects I've written over the years have been as complex as Lwan ended up being: most of them were nothing but weekend hacks and were never able to hold my attention for more than a few dozen hours.
It's to be expected, then, that I might have a thing or two to say about it. In fact, I've been doing this in homeopathic doses over the almost two years since I've started the project. Never actually connected all the dots, leaving out important details.
This article is an attempt to describe, from the perspective of Lwan, the life of a HTTP request — from the socket being accepted to the response being sent — and explaining details and reasoning behind the implementation.
Creating the listening socket & accepting connections
There's nothing really special here: sockets are either created using the standard POSIX stuff, or are passed down from systemd. In either case, TCP Fastopen and Quickack are enabled, in addition to socket lingering. The socket is left in its default, blocking mode. The listen() backlog is the maximum allowed by the system.
static int
#ifdef SOMAXCONN
int backlog = SOMAXCONN;
int backlog = 128;
FILE *somaxconn;
somaxconn = fopen("/proc/sys/net/core/somaxconn", "r");
if (somaxconn) {
int tmp;
if (fscanf(somaxconn, "%d", &tmp) == 1)
backlog = tmp;
return backlog;
It's a blocking file descriptor since the main thread (responsible for accepting all the sockets and scheduling clients) blocks on a call to accept4() instead of something like Epoll. This accept() variant is Linux-only and, among other things, lets one specify flags in sockets without requiring an additional round trip to the kernel; the only flag that interests Lwan is SOCK_NONBLOCK.
lwan_main_loop(lwan_t *l)
if (setjmp(cleanup_jmp_buf))
signal(SIGINT, _signal_handler);
lwan_status_info("Ready to serve");
for (;;) {
int client_fd = accept4(l->main_socket, NULL, NULL,
if (UNLIKELY(client_fd < 0)) {
_schedule_client(l, client_fd);
File descriptor limits are raised to the maximum allowed by system settings — at which time, Lwan pre-allocates an array of structures to hold connection state for all possible file descriptors.
Scheduling connection
In order to multiplex connections, Lwan spawns one thread per logical CPU, and uses Epoll to determine which socket is ready to be written to or read from. Once a connection is scheduled to one of these threads, it stays there until it is explicitly closed or a timeout occurs.
All threads share the preallocated connection array, and there are no explicit locks. The index to this array is the connection file descriptor, which makes lookup very quick. This exploits the notion that file descriptors are always allocated from the lowest possible number.
struct lwan_connection_t_ {
/* This structure is exactly 32-bytes on x86-64. If it is
* changed, make sure the scheduler (lwan.c) is updated as
* well. */
lwan_connection_flags_t flags;
unsigned int time_to_die; /* In seconds since DQ epoch */
coro_t *coro;
lwan_thread_t *thread;
int prev, next; /* For death queue */
Since this structure is quite small, this leads to a form of implicit lock called false sharing, which is solved with a scheduler that is aware of that problem and groups two connection structures per cache line. It's simpler than it sounds:
int thread = ((fd - 1) / 2) % n_threads;
A round robin scheduler is used on other architectures.
An interesting curiosity about the connection structure is that it doesn't store the file descriptor: pointer arithmetic is performed to obtain it, as the the base address for the connection array is known.
ALWAYS_INLINE int
lwan_connection_get_fd(lwan_connection_t *conn)
return (int)(ptrdiff_t)(conn - conn->thread->lwan->conns);
After a thread has been chosen by the scheduler, the file descriptor number is sent to a Unix domain socket created with socketpair() to that particular thread's Epoll. This part used to use epoll_ctl() directly — which, although threadsafe, had a problem: epoll_wait() will never timeout on a socket if nothing was read from it previously. By writing to that socketpair, Epoll awakens, the file descriptor is added to it, and that thread's death queue can handle the timeout by itself.
The sole purpose of each thread is to react to Epoll events, such as:
- Timeouts (in which case the death queue iterates, potentially terminating connections);
- Epoll errors (in which case the thread finishes gracefully);
- Readiness events (can read, can write);
- Connection hung up.
Epoll events are used as signals to create, destroy, resume, and reset coroutines: there's one for each connection, and they're used both as lightweight threads and as resource management facilities.
Coroutines provides a reasonably simple model for asynchronous I/O handling that's less convoluted than the dreaded callback idiom prevalent in C. They also require a lot less stack space than a thread and their creation is pretty efficient: essentially just a call to malloc().
coro_t *
coro_new(coro_switcher_t *switcher,
coro_function_t function,
void *data)
coro_t *coro = malloc(sizeof(*coro) + CORO_STACK_MIN);
if (!coro)
return NULL;
coro->switcher = switcher;
coro->defer = NULL;
/* coro_reset() is just a few assignments on x86-64 */
coro_reset(coro, function, data);
#if !defined(NDEBUG) && defined(USE_VALGRIND)
char *stack = (char *)(coro + 1);
coro->vg_stack_id = VALGRIND_STACK_REGISTER(stack,
stack + CORO_STACK_MIN);
return coro;
Request handlers can be written using an API that's completely synchronous on the surface but behind the curtains, I/O happens in the background (client sockets are non-blocking) and control is given to the next coroutine as commanded by each thread's loop.
Execution resumes where the coroutine left off. This saves a lot of code, not only making things easier to reason about, but also simplifying resource management by having a single cleanup point.
To provide a synchronous-looking API, Lwan provides a few wrappers for common operations, such as writev() or sendfile(). Unlike the functions these wrap, they return no error:
- On success, the same return code is returned;
- Recoverable errors (such as EINTR) are handled by trying them again a few times before giving up;
- When giving up, or on unrecoverable errors, coroutines are aborted.
lwan_openat(lwan_request_t *request,
int dirfd, const char *pathname, int flags)
for (int tries = max_failed_tries; tries; tries--) {
int fd = openat(dirfd, pathname, flags);
if (LIKELY(fd >= 0)) {
* close() will be called as soon as the
* coroutine ends
coro_defer(request->conn->coro, CORO_DEFER(close),
(void *)(intptr_t)fd);
return fd;
switch (errno) {
case EINTR:
case EMFILE:
case ENFILE:
case ENOMEM:
return -errno;
return -ENFILE;
When a coroutine is destroyed, user-defined callbacks are executed. These include callbacks set by the wrapper functions, to close files, free memory, and perform many other cleanup tasks. This ensures resources are released regardless if the coroutine ended normally or an unrecoverable error has been detected.
On supported architectures, coroutine context switching is almost as cheap as a function call. This is possible because hand-written assembly routines are used, which only performs the essential register exchange, as mandated by the ABI. There is still some work to do in order to speed up this; tricks used by libco, for instance, might be used in the future to reduce some of the overhead.
On every other architecture, swapcontext() is used and this usually incurs in saving and restoring the signal mask, in addition to swapping every register (including those not required by the calling convention); this might change to setjmp() in the future to avoid at least the two system calls.
Another use for coroutines in Lwan is inside the Mustache templating engine, described in more depth below.
Reading requests
The loop within each I/O thread is quite crude.
Essentially, a coroutine will only be resumed for reading once per request: once it yields, Epoll will only be interested in write events. Because of this, reading a request uses a purpose-built read() wrapper that tricks the scheduler to still be interested in read events, unless the request has been fully received (by ending with the "␍␊␍␊" separator).
As soon as the whole request has been received, it is then parsed and acted upon.
Parsing request
Request parsing in Lwan is quite efficient: there are no copies, no memory allocations from the heap. The buffer is modified in place by slicing and storing pointers to stuff the server might be interested in. Parsing of HTTP request headers is delayed until needed (and they might not be needed).
struct lwan_request_parse_t_ {
lwan_value_t buffer; /* The whole buffer */
lwan_value_t query_string; /* Stuff after URLs ? */
lwan_value_t if_modified_since; /* If-Modified-Since: */
lwan_value_t range; /* Range: */
lwan_value_t accept_encoding; /* Accept-Encoding: */
lwan_value_t fragment; /* Stuff after URLs # */
lwan_value_t content_length; /* Content-Length: */
lwan_value_t post_data; /* POST data */
lwan_value_t content_type; /* Content-Type: */
lwan_value_t authorization; /* Authorization: */
char connection; /* k=keep-alive, c=close */
Among other things, one that often receives comments is how headers are parsed. Two tricks are involved: avoiding spilling/filling registers to compare strings with strncmp(), and applying a heuristic to avoid reading (and comparing) more than necessary. Both tricks are intertwined into a "string prefix switch":
- Four bytes are read from memory, and are cast to a 32-bit integer pointer;
- That pointer is then dereferenced;
- A standard switch statement is used to perform cheap comparisons on a 32-bit integer;
- When a header prefix is matched, a simple heuristic of finding the
separating colon and space character where they're supposed to be is used.
- This might give false positives, although that's very unlikely in practice.
Once the request has been parsed, it is time to look up what is going to handle it.
Looking up handler
A prefix tree is used to look up handlers. It is a modified trie data structure that has only eight pointers per node, so that on x86-64, each node fills one cache line exactly. This is achieved by hashing each character used to build up a node by taking the 3 least significant bits.
struct lwan_trie_node_t_ {
lwan_trie_node_t *next[8];
lwan_trie_leaf_t *leaf;
int ref_count;
The canonical and naïve alternative to the hashed trie is having 256 pointers per node, which puts too much virtual memory pressure: the approach used in Lwan is a good compromise between keeping this pressure low and implementation complexity.
Another alternative (which might be considered in the future) is to reduce the amount of nodes by coalescing common prefixes; this significantly increases implementation complexity, though, but combined with the string switch trick, this might yield a good performance boost.
Yet another technique investigated was to generate machine code to perform lookup: essentially turning a data structure into executable code. The idea works but the instruction cache pressure isn't worth the trouble. I'm still partial to this solution, though, so I might revisit it later: Varnish does something remotely similar with VCL and it seems to work, so this deserves a little bit more research.
After a handler is found, a second round of parsing might happen. Each handler contains a set of flags that signal if headers (which were sliced in the request parsing stage) should be actually parsed. This include headers such as Range, Accept-Encoding, If-Modified-Since, and authorization stuff. Handlers that do not require parsing these headers will not trigger potentially expensive string crunching.
typedef enum {
} lwan_handler_flags_t;
To reduce the amount of boilerplate necessary to declare a handler, there's a shortcut that parses almost everything; these are the "request handlers", such as the "Hello world handler" example shown below.
Modules, on the other hand, provide much more fine-grained control of how the request will be handled; an example is the static file serving feature, also discussed further down.
static const lwan_module_t serve_files = {
.name = "serve_files",
.init = serve_files_init,
.init_from_hash = serve_files_init_from_hash,
.shutdown = serve_files_shutdown,
.handle = serve_files_handle_cb,
.flags = HANDLER_REMOVE_LEADING_SLASH
Hello world handler
The simplest handler possible is a "Hello, World!". This tests the raw read-parse-write capacity of Lwan, without requiring more system calls than absolutely necessary.
hello_world(lwan_request_t *request __attribute__((unused)),
lwan_response_t *response,
void *data __attribute__((unused)))
static const char *hello_world = "Hello, world!";
response->mime_type = "text/plain";
strbuf_set_static(response->buffer, hello_world,
return HTTP_OK;
These simple handlers will use whatever is inside their respective string buffers (which is an array that grows automatically when needed, with some bookkeeping attached). In the "Hello, World!" case, however, the string buffer acts merely as a pointer to some read-only string stored in the text section; this simplifies the interface a little bit, while avoiding string copies and unneeded heap allocations.
Chunked encoding and Server-sent events
Supported also is the Chunked Encoding. Using it is very simple: just set the response MIME Type, fill the string buffer, and call lwan_response_send_chunk(). From this point on, the response headers will be sent alongside the first chunk, the string buffer will be cleared, and the coroutine will yield. To send the next chunk, just fill the string buffer again and send another chunk, until your handler is complete.
test_chunked_encoding(lwan_request_t *request,
lwan_response_t *response,
void *data __attribute__((unused)))
response->mime_type = "text/plain";
strbuf_printf(response->buffer, "First chunk\n");
for (int i = 0; i <= 10; i++) {
strbuf_printf(response->buffer, "*Chunk #%d*\n", i);
strbuf_printf(response->buffer, "Last chunk\n");
return HTTP_OK;
The same general idea is used by Server-sent events; however, one uses lwan_response_send_event(), and passes the event name as well.
test_server_sent_event(lwan_request_t *request,
lwan_response_t *response,
void *data __attribute__((unused)))
for (int i = 0; i <= 10; i++) {
strbuf_printf(response->buffer, "{n: %d}", i);
lwan_response_send_event(request, "currval");
return HTTP_OK;
The implementation inside Lwan is as straightforward as it looks: coroutines saved the day.
File serving module
Since files can be served using the sendfile() system call, the kind of handlers used by Hello World can't be used: responses are sent using writev() to send both response headers and contents in one kernel roundtrip. Because of this, there's a different kind of handler that gives more control as to how the response is sent: the (for the lack of a better name) streaming handlers. Streaming handlers are expected to send the whole response themselves.
To convert a "normal" handler into a streaming handler is simple: just set a few pointers in the "normal" handler and return. With the exception of producing error responses automatically — streaming handlers function exactly the same as a "normal" handler that does not send the response headers automatically.
static lwan_http_status_t
serve_files_handle_cb(lwan_request_t *request,
lwan_response_t *response, void *data)
lwan_http_status_t return_status = HTTP_NOT_FOUND;
serve_files_priv_t *priv = data;
struct cache_entry_t *ce;
if (UNLIKELY(!priv)) {
return_status = HTTP_INTERNAL_ERROR;
goto fail;
ce = cache_coro_get_and_ref_entry(priv->cache,
request->conn->coro, request->url.value);
if (LIKELY(ce)) {
file_cache_entry_t *fce = (file_cache_entry_t *)ce;
response->mime_type = fce->mime_type;
response->stream.callback = fce->funcs->serve;
response->stream.data = ce;
response->stream.priv = priv;
return HTTP_OK;
response->stream.callback = NULL;
return return_status;
To avoid having to obtain information about a file for every request, this information is cached for a few seconds. The caching mechanism itself is discussed in detail further down.
While caching file information, the file size is considered while picking the way to serve it. Files larger than 16KiB are served with sendfile() to allow zero (or fewer) copy transfers, and smaller files are mapped in memory using mmap().
static const cache_funcs_t *
_get_funcs(serve_files_priv_t *priv, const char *key,
char *full_path, struct stat *st)
char index_html_path_buf[PATH_MAX];
char *index_html_path = index_html_path_buf;
if (S_ISDIR(st->st_mode)) {
/* It is a directory. It might be the root directory
* (empty key), or something else. In either case,
* tack priv->index_html to the path. */
if (*key == '\0') {
index_html_path = (char *)priv->index_html;
} else {
/* Redirect /path to /path/. This is to help
* cases where there's something like <img
* src="../foo.png">, so that actually
* /path/../foo.png is served instead of
* /path../foo.png. */
const char *key_end = rawmemchr(key, '\0');
if (*(key_end - 1) != '/')
return &redir_funcs;
if (UNLIKELY(snprintf(index_html_path, PATH_MAX,
"%s%s", key,
priv->index_html) < 0))
return NULL;
/* See if it exists. */
if (fstatat(priv->root.fd, index_html_path, st, 0) < 0) {
if (UNLIKELY(errno != ENOENT))
return NULL;
/* If it doesn't, generate a directory list. */
return &dirlist_funcs;
/* If it does, we want its full path. */
if (UNLIKELY(priv->root.path_len + 1 /* slash */ +
strlen(index_html_path) + 1 >= PATH_MAX))
return NULL;
full_path[priv->root.path_len] = '/';
strncpy(full_path + priv->root.path_len + 1,
PATH_MAX - priv->root.path_len - 1);
/* It's not a directory: choose the fastest way to serve the
* file judging by its size. */
if (st->st_size < 16384)
return &mmap_funcs;
return &sendfile_funcs;
Small files may also be compressed, unless compressed data ends up being larger than the original data. Especially if the response header is considered. Because of this, small files are only compressed if it's worth the trouble. The 16KiB threshold has been chosen empirically: larger values did not yield substantial performance gains compared to using sendfile().
static void
_compress_cached_entry(mmap_cache_data_t *md)
static const size_t deflated_header_size =
sizeof("Content-Encoding: deflate");
md->compressed.size = compressBound(md->uncompressed.size);
md->compressed.contents = malloc(md->compressed.size);
if (UNLIKELY(!md->compressed.contents))
goto error_zero_out;
int ret = compress(md->compressed.contents,
if (UNLIKELY(ret != Z_OK))
goto error_free_compressed;
size_t total_size = md->compressed.size
+ deflated_header_size;
if (total_size < md->uncompressed.size)
md->compressed.contents = NULL;
md->compressed.size = 0;
For directories, the template engine is used to create the listing. The contents are cached using the same mechanism files are. Templating is discussed below.
An interesting optimization is that, to obtain the full path, a special version of realpath(), forked from the GNU libc implementation, is used. This version uses the lighter "-at()" variants of system calls that operates on paths; they do not need to perform path-to-inode conversion for the whole path, only from a path pointed to by a directory file descriptor.
The file server is a module. It is a simple way to keep per instance state, such as the file descriptor for the root directory, the directory list template, and a few other things.
Mustache templating engine
Not all features from Mustache are implemented: some are pretty much only practical if using a language that's more expressive than C. However, without requiring (too much) boilerplate, a substantial amount of its specification is implemented, in a pretty efficient way, and suits all Lwan uses pretty well. (Being performant might not matter, though, but I'm here to have fun, not solve problems.)
Not everything is implemented exactly as in the standard, though: that's mostly for laziness reasons, but the non-dynamic nature of C would make certain things needlessly difficult to implement and use, anyway. The templating engine supports the basic stuff. In no particular order:
- Variables of different types;
- Checking the emptiness of variables;
- Iteration on lists (and any kind of sequences);
- Partials;
- Comments;
- Inverted sections.
Setting the delimiters, triple mustaches (for escaping HTML output), ampersand to unescape strings — and possibly other things — are not implemented, but could be implemented with relatively minimal effort. String escaping is supported by using a special string type and should conform to best practices.
Templates are pre-processed. This pre-processing step uses a state machine parser to break down its text representation into a series of actions that can be performed by the engine very efficiently. Actions include things like "append string", "append variable", "start iteration", and so on.
typedef enum {
} lwan_tpl_action_t;
For instance, a stack of hash tables is used during this pre-processing step to act as a symbol table; this table can be thrown away as soon as the pre-processing step is complete, as all variables have been resolved and a much more efficient value lookup mechanism can be used instead.
Obtaining variables
To use the templating mechanism, one should have a structure for each template. Structures are cheap and provide some welcome compile-time type checking that wouldn't be possible otherwise.
typedef struct hello_t {
char *name;
int age;
In addition to a structure, due to the lack of introspection in C, an array of variable descriptors should be declared. A variable descriptor contains a string representation of a variable name, the offset in bytes of that variable within the structure, and pointers to functions to test the emptiness of that kind of variable and to append the variable to the string buffer; macros help alleviate boilerplate headaches.
lwan_var_descriptor_t hello_descriptor[] = {
TPL_VAR_STR(hello_t, name),
TPL_VAR_INT(hello_t, age),
lwan_tpl_t *hello = lwan_tpl_compile("hello.tpl",
A structure containing all the variables can then be supplied by some sort of database layer, caching layer, or be declared on the spot: compound literals with designated initializers make this use case pretty straightforward.
strbuf_t *rendered = lwan_tpl_render(hello, (hello_t[]) {{
.name = "World",
.age = 42
/* Do something with `rendered` */
Appending a variable is then just the matter of calling the appropriate callback function (conveniently in the descriptor), passing the base address of that structure plus the byte offset within it.
static void
append_var_to_strbuf(lwan_tpl_chunk_t *chunk, void *variables,
strbuf_t *buf)
lwan_var_descriptor_t *descriptor = chunk->data;
if (LIKELY(descriptor))
(char *)variables + descriptor->offset);
To avoid creating potentially lots of small, temporary objects, for lists and sequences a coroutine is created and is used as a makeshift generator function. Another option was to implement iterators using a structure to hold state plus a few callbacks — I gave up while imagining the amount of boilerplate necessary. A function is simple to write on the other hand, and can include initialization, iteration, and cleanup.
The only user of sequences in templates within Lwan is the file listing feature in the file serving module. The generator function is pretty straightforward, and is responsible for opening the directory, obtaining information for each entry, and then closing the directory. A shorter version of it is described in the original blog post about sequences in the templating engine.
I've used and implemented a few caching infrastructures over the years, and I believe that the one in Lwan is, so far, the simplest one I've used. Most caches will require items to be created — and then added manually to the cache. Not only clumsy, but could also lead to race conditions.
The one in Lwan knows how to create and destroy a cache entry: one just asks the cache to obtain a value for a given key. If it's not there, the entry is created and returned. The lifetime of a cache entry is controlled automatically, and a low priority thread kicks in every now and then to prune old entries.
struct cache_t {
struct {
struct hash *table;
pthread_rwlock_t lock;
} hash;
struct {
struct list_head list;
pthread_rwlock_t lock;
} queue;
struct {
CreateEntryCallback create_entry;
DestroyEntryCallback destroy_entry;
void *context;
} cb;
struct {
time_t time_to_live;
clockid_t clock_id;
} settings;
unsigned flags;
#ifndef NDEBUG
struct {
unsigned hits;
unsigned misses;
unsigned evicted;
} stats;
Unlike most caches, the one in Lwan isn't limited by size: items stay in the cache for a predetermined amount of time.
Cache entries are reference-counted, and they're not automatically reaped if something is holding on a reference: these items are marked as floating when this happens, and the last one to give up the reference will also destroy the entry.
struct cache_entry_t {
struct list_node entries;
char *key;
unsigned refs;
unsigned flags;
struct timespec time_to_die;
struct file_cache_entry_t_ {
struct cache_entry_t base;
struct {
char string[31];
time_t integer;
} last_modified;
const char *mime_type;
const cache_funcs_t *funcs;
When used within a coroutine, two things can happen: ➀ the coroutine might yield if the cache lock were to become contended and ➁ automatically releasing a reference when a coroutine is destroyed.
In addition to floating entries, there are also temporary entries. The cache uses read-write locks, but most of the time, locks are only obtained using the "trylock" primitive: if a lock can't be obtained for a reason, Lwan tries to move on to something else. This could be attending to another request (by yielding the coroutine), or merely returning an off-the-books entry that will be destroyed as soon as its sole user releases its reference. The difference to floating entries is merely an implementation detail, so that an atomic decrement (and its accompanying memory barrier) isn't used.
The cache tries to avoid keeping the locks locked. As an example, while an item is being created, no locks are held. This can, of course, lead to multiple entries being created concurrently, but if caching would be useful anyway, having a few temporary entries lying around isn't a problem, as at least one will be cached for future access.
As nice as the cache subsystem ended up being, there is a lot of room for improvement. Reducing the amount of concurrent reference counting is high on the list. Reducing the latency is also in consideration. Making HTTP responses cacheable without special code in the handler is there as well.
Keep-alive connections, death queue
Connection lifetime is managed by a per-thread queue.
Each time a connection is scheduled to a certain thread, it is pushed to the queue, and a time to die is set. When there are connections in this queue, Epoll will timeout every second to iterate through it and kill connections when their time has come. Timeouts are infinite when the queue is empty, to avoid waking the process unnecessarily. Every time a coroutine is resumed, the time to die is updated, and the connection is pushed to the end of the queue.
Each death queue has its own epoch, which starts at zero and increments at every timeout. Whenever the last connection is removed from a queue, the epoch restarts. Keeping the epoch a small number will help shave a few bytes from each connection in the future.
struct death_queue_t {
lwan_connection_t *conns;
lwan_connection_t head;
unsigned time;
unsigned short keep_alive_timeout;
The same timeout value is used for keep-alive connections and coroutines. This ensures coroutines will not linger indefinitely when not performing any kind of work.
The death queue is so important that almost a third of the connection structure is dedicated to its existence. Three integers keep state for the death queue: the time to die (as an unsigned int), and two integers as pointers to a doubly linked list.
Integers were used instead of pointers in order to save memory. This was possible since in reality they are indices to the connection array. A doubly linked list was also chosen since removing a connection from the middle of the queue should be efficient, as it is done very frequently to move the entry to the end. The list is also circular, in order to avoid branching to handle empty queue cases. Maintaining the queue inline with the connection structures help reducing cache pressure.
static inline int _death_queue_node_to_idx(
struct death_queue_t *dq, lwan_connection_t *conn)
return (conn == &dq->head) ?
-1 : (int)(ptrdiff_t)(conn - dq->conns);
static inline lwan_connection_t *_death_queue_idx_to_node(
struct death_queue_t *dq, int idx)
return (idx < 0) ? &dq->head : &dq->conns[idx];
static void _death_queue_insert(struct death_queue_t *dq,
lwan_connection_t *new_node)
new_node->next = -1;
new_node->prev = dq->head.prev;
lwan_connection_t *prev = _death_queue_idx_to_node(dq,
dq->head.prev = prev->next = _death_queue_node_to_idx(dq,
static void _death_queue_remove(
struct death_queue_t *dq, lwan_connection_t *node)
lwan_connection_t *prev = _death_queue_idx_to_node(dq,
lwan_connection_t *next = _death_queue_idx_to_node(dq,
next->prev = node->prev;
prev->next = node->next;
Closing words
That's pretty much it: when a response has been sent, the connection can either be closed, or a new request can be serviced in the same connection. Repeat ad infinitum and there's the HTTP server.
If you've made this far, I invite you to take a look at the full source code. There are things that were not mentioned in this article. It's also a young Free Software project with no entry barrier: just fork and issue a pull request.


text:
LOCATION, LOCATION, LOCATION! Brand new, and absolutely stunning... these downtown Farmington townhomes are just what you've been looking forward! Loaded with TONS of upgrades, including a finished basement, stainless steel appliances with a gas range, stone countertops and custom cabinets in kitchen and all bathrooms, 30 year shingles on the roof and classy Hardie board siding on the exterior. These homes are conveniently located right off of state street for easy access to I-15, Farmington Station, and some great local restaurants. Reserve your lot today!
Information deemed reliable but not guaranteed accurate. Buyer to verify all information.
The multiple listing information is provided by Wasatch Front Regional Multiple Listing Service, Inc. from a copyrighted compilation of listings. The compilation of listings and each individual listing are © 2020 Wasatch Front Regional Multiple Listing Service, Inc., All Rights Reserved.
The information provided is for consumers' personal, non-commercial use and may not be used for any purpose other than to identify prospective properties consumers may be interested in purchasing.

subset: commoncrawl


text:
As we say 'You Dream, We Develop', we work diffrently and achieve the solution in a smart way. Our team is always focused on creativity. We forge partnerships founded on collaboration.
We have years of experienced developers providing outstanding service from around the world. Our development team is always focused on simplicity, user friendly, creative and professional development.
Sirseni SoftTech not only designs your website professionally but we also host your website in very secured server. We provide you free support and even a domain for free with every hosting.
We don't only sell our service but also provide outstanding support through various way and help you to grow your business with our services because we want to build professional business relationship with you.
In this time, more than 50% of the people use internet through their handy devices like Smart Phones and Tablets. Our design will be compatible in all those devices and even Laptops, Desktop and Smart TVs.
Dynamic or CMS website is that which allow admin of the website to edit, delete and manage the website easly without coding. If your website needs to be updated regularly then, this is right selection.
If you want to sale your products or services on the internet you must have a e-commerce website. E-commerce website allows you to sale products and services online and make payment online.
We develop mobile application for android, IOS and windows platform. If you want a mobile application on any platform for your business, Sirseni SoftTech can be right solution.
If you have dreamed of makingg your own web application or want to re-design or re-develop, Sirseni SoftTech can be your right solution to power your small and large web applications.
We have creative and experienced team to design your personal or business logo, banner, magazine, and user interface for website, software and mobile application in very reasonable price.


text:
February 25, 2016
Still a Match?
So she decided to try an experiment. They would create profiles on a popular dating site and see if it matched them. That, she decided, would prove that they were still compatible. Or not.
Wagner's Washington Post article describes what happened next, and what the unexpected result really proved.
Subscribe to: Post Comments ( Atom )


text:
Hiya Girlies!
Oh my gosh, I have missed my blog so freaking much!
However I can say that my studies are now finished, for good, and I am well and truly back!
I have such a long list of blog posts, as long as my arm, to catch up on, that I really did not know where to start, but what better way to start back than with a product review on the Spa Find Renewed Radiance Energizing Day Cream!
A little bit about how I got to try this....
I have currently been studying Fda Spa Therapies, and of course with the studies, comes the product training, and what better company to have it with, than with Spa Find!
Spa Find are a brand established since 1981, who use a skin-friendly formula containing plant extracts of horsetail marshmallow and rosemary, with Harmonised water, pure dead sea minerals, Vitamin E, B5, VMS Complex, Chamomile and promise to be free from parabens, allergen-free fragrance, animal products, GMOs and are against animal testing. Sounds promising already doesn't it?
During product training, we were given a bag containing a few samples, which of course we fascinated by. I got so excited about the products that I had to instagram a picture of my samples immediately and decided to tag @spafind in them too, though I never expected them to like my picture and comment on it too.
After trying my sample of the Renewed Radiance Energizing Day Cream, I again had to instagram a picture to say how much I liked the product, and as a result, to my complete surprise, I was very kindly sent a full sized product, canvas bag, product booklet and offer leaflet in the post! I could not have been more Excited!
The company never asked me to review the product, and sent it out of pure generosity, however I loved the product so much that I just had to write a review to let you guys know all about it.
Although I would never take this long to review a product usually, with studies in the way, I had no choice, but on the positive side, I have now had the opportunity to review this product for a whole three weeks, and have a clearer opinion about the products and the results you can receive.
The Spa Find Renewed Radiance Energizing Day Cream is recommended for dry, mature and sensitive skin, and contains SPF 15. I think SPF is such an important factor to have in skincare products, as I think it's easy to forget about using protection for the face, however we need to protect out faces from those harmful sun rays too. Although my skin is not mature, it is dry and it is sensitive, so I did not have any queries about trying the product, in fact I think it suits my skin perfectly, and I don't think you can ever try early enough to keep the wrinkles at bay.
After using this product for three whole weeks with my usual skin care routine, I have noticed that my smile lines, which are a major insecurity for me, have visibly reduced, my skin is noticeably smoother and my foundation is no longer attaching to the dry areas of my skin, as my skin is much more hydrated.
These results have come from using the product alone, and not with the recommended cleanser, toner and night cream from the same range, so I am amazed at the results that I am already receiving.
The product is a smooth and creamy consistency, and you only need to apply a small amount daily, it smells lovely and fresh like sand, a strange description, I know, but I think this derives from the dead sea minerals within the product, and once you smell it, you'll know what exactly what I mean.
Overall I would definitely recommend the product, especially alongside the recommended products for best results, and a positively glowing complexion.
Have you tried Spa Finds products yet?
Love Abbie x
Thankyou for reading my blog, I hope you liked it and don't forget to follow me beautifuladdiction21 on Instagram, shesaidbeauty and glipho xx


text:
10:14 am
September 30, 2010
The Personal Bill of Rights
1. Life should have choices beyond mere survival.
2. You have the right to say no to anything when you feel you are not ready or it is not safe.
3. Life should not be motivated by fear.
4. You have a right to all of your feelings.
5. You are probably not guilty.
6. You have a right to make mistakes.
7. There is no need to smile when you cry.
8. You have a right to terminate conversations with people who make you feel put down or humiliated.
9. You can be healthier than those around you.
10. It is OK to be relaxed, playful, and frivolous.
11. You have a right to change and grow.
12. It is important to set limits and be selfish.
13. You can be angry at someone you love.
14. You can take care of yourself, no matter what circumstances you are in.
10:25 am
September 30, 2010
11:02 am
September 30, 2010
7:18 pm
September 29, 2010
7:31 pm
September 30, 2010
8:42 pm
September 24, 2010
OH Kathy!
Thanks for this.
I have to post at least 8 of the 10.
I get a little agitated that this stuff doesn't come naturally to me.
What I mean is, I've seen seven year olds with clearer understanding of their Personal Bill of Rights than I have sometimes.
Well, You live, and you learn, and you take it one day at a time, RIGHT GIRLS!!!
8:56 pm
September 30, 2010
9:19 am
September 24, 2010
I DID IT: Posted them on the Fridge.
Comitted most to memory.
Now I feel as mature as any 7 year old about my personal rights.
HA! In your face Courtney, and Jessica, and Lisa.
And now that I know my rights, things are gonna change...
The next time I pick you up in my car, and take you to my house to watch Powerpuff Girls on my tv: I get to be Blossom.
12:04 pm
September 30, 2010
Boosting this up (thanks again Kathy), as well as a little something that came up in the search box with it that I thought was very interesting.
Thought'd we'd all benefit from this; my therapist gave it to me last week. 🙂
YOU HAVE A RIGHT... -to put yourself first, sometimes. -to make mistakes. -to be the final judge of your feelings and to accept them as legitimate. -to your own opinions and convications. -to change your mind or choose a different course of action. -to protest unfair treatment or criticism. -to negotiate for change. -to ask for help or emotional support. -to ignore the advice of others. -to say "NO." -to be aone, even if others would prefer your company. -not to take responsibilty for someone else's problem.
IT IS NEVER YOUR RESPONSIBILITY TO... -give what you really don't want to give. -sacrifice your integrity to anyone. -do more than you have time to do. -drain your strength for others. -listen to unwise counsel. -remain in an unfair relationship. -conform to unreasonable demands. -be 100% perfect. -follow the crowd. -put up with unpleasant situations. -please unpleasant people. -bear the burden of another's misbehavior. -do something you really cannot do. -love unloveable people. -feel guility about your inner desires. -submit to overbearing conditions. -apologize for being yourself. -meekly let life pass you by. -be anyone but EXACTLY who you are.
12:18 pm
September 24, 2010
12:24 pm
September 29, 2010
12:25 pm
September 30, 2010
3:17 pm
September 27, 2010
Hi Flower,
My mom just stopped by to fill me up with "unwise counsel" about staying married for the sake of the children and because all men are losers anyway and it's unrealistic of me to expect to find a "prince charming" - which I don't, btw, just a healthy adult, please.
I was feeling low and guilty for not towing the family line, and reading this has given me a ton of encouragement and strength. It's wonderful to have a place to come for the wise counsel I unfortunately could never get from my nutty parents.
A big hug to you, and
Thanks for helping with my "reparenting".
3:23 pm
September 30, 2010
10:22 pm
September 30, 2010
Actually, everyone, it was Kathygy who posted the bill of rights (if you click on 'view all posts', it's really excelent) and "babysteps" who I have never met, who posted the second part seen at the top in 2004. Just thought some of us could really use these both right now, all I did was bump it up while looking for it for myself...again, Thanks to Kathy and Babysteps for this!!!
11:10 pm
September 30, 2010
1:03 am
September 30, 2010
1 Guest(s)


text:
Landscape Sales Designer
Grunder Landscaping Co. is currently seeking a talented Landscape Sales Designer with a proven track record of increasing sales by producing outstanding creative landscape and hardscape designs for fine homes and properties.
Position Description
As a key member of the Grunder team, you will be responsible for:
- Generating leads and conducting client consultations that lead to sales
- Creating and preparing design proposals and cost estimates for residential and commercial properties based on accurate field verifications, measurements, and analyses
- Serving as the primary contact for new and existing clients and ensuring those relationships are fostered and maintained
- Working with team members throughout the company to coordinate installations
- Being a voice and face for Grunder Landscaping in the local community and in company marketing materials
Position Requirements
Our ideal candidate is an excellent communicator and organizer who is results-driven, assertive, efficient, and a team player. He or she has:
- A bachelor's degree in landscape architecture or landscape design, or a demonstrated depth of horticulture knowledge from prior landscape design experience. State or national landscape industry certification(s) preferred
- A minimum of five years' landscape and hardscape design experience in a position (or positions) that involved obtaining business, working directly with residential and commercial clients, and coordinating installations. Prior experience increasing sales through lead generation and community involvement strongly preferred
- Significant knowledge of horticultural materials suitable for Ohio and proper planting techniques, along with an understanding of landscaping construction products, methods, and procedures. Prior experience installing plants and/or hardscaping materials a plus
- Proficiency with AutoCad and Microsoft Office
- A valid driver's license
Because this position serves as the primary contact for new and existing clients, the candidate we seek must be friendly, genuine, confident, bright, and professional, with a talent for building rapport quickly.
Compensation and Benefits
If you've got what it takes, we'll provide the rest. You'll join a company with a stellar reputation and enjoy significant lead potential, along with:
- A compensation plan with a generous base and unlimited earning potential based on sales
- Paid holidays and paid time off
- Medical, dental, life, and supplemental insurances
- A 401(k) plan with company match
- A company vehicle and phone
- A family atmosphere, with additional benefits
How To Apply
If you're ambitious, dependable, and eager to join a company you can be proud of, we'd love to talk to you! For confidential consideration, please email your résumé, a letter of interest, and your compensation history to email@example.com.
Pre-employment drug testing and background/driving checks required.
At Grunder Landscaping Co., equal talent will always get equal opportunity.
Thank you for your interest in Grunder Landscaping Co. We are always looking for talent, so if you know someone who'd be a great addition to our team, please pass the word on.


text:
How Open Data Can Help Tackle Corruption – Policy Paper
This policy paper provides a summary of our research into how open data can be used to tackle corruption. This research involved analysing 95 case studies of corrupt behaviour and identifying the primary method of finding this information.
We found that whilst open data has not historically been used to identify incidents of corruption in the UK it can be used to deter and detect corrupt acts, and should be an integral part of the UK's anti-corruption toolkit.
The research also identified particular types of data that could be more relevant to specific types of corrupt behaviours, and found that open data's role in tackling corruption can differ dramatically depending on whether the behaviour is illegal or not. Law enforcement investigations appear to be the best method of identifying criminal activity, whilst open data can play a more powerful role in informing public debate about activity that is not technically illegal or a breach of certain rules, but nevertheless ethically questionable.
Recommendations for change
Based on this research, we have made 45 proposals for the UK Government and public bodies to take forward as part of its UK Anti-Corruption Plan. TI-UK has also made three major recommendations that they should take forward as a matter of priority:
- The UK Government should empower an open data authority with the necessary resources and powers to maintain consistent standards of proactive disclosure across the public sector and public services that are outsourced to the private sector.
- The UK Government should bring forward legislation to reform the statutory register of lobbyists, so it covers both in-house and consultant lobbyists and provides meaningful detail about lobbying activities in the UK.
- To improve detection and deterrence of lobbying abuses we recommend the UK Government:
- Improves the timeliness and quality of data published about meetings between lobbyists and Ministers, Permanent Secretaries and Special Advisers.
- Extend this proactive publication to include minutes of meetings involving major decisions.
- Publish details of all secondments to and from private sector.
The TACOD project was co-funded by the Prevention of and Fight against Crime Programme of the European Union.
- Report published: Jun 2015


text:
I can't wait until I meet Anthony Bourdain, its going to be a hoot and we are just going to hit it off. Until then, I'll post about Tony's journey from the kitchen to social issues. One of my favorite shows ever is "Parts Unknown." I was fairly easily able to find a transcript of one of the most interesting episodes that highlights life in Mexico and struggles faced there. I know this article doesn't specifically address health. However, there is something to be learned about the ease in which he is able to jump from something that can be considered more trivial, or less serious, like street food, to deeply rooted societal social issues. Here is a Washington Post article he wrote on his episode on Iran and I really enjoyed his Beirut article. He is the master storyteller, and if he could ever incorporate or tackle health issues, it would be amazing.
The one thing that is definitely health related is the food he showcases. As I've learned in class, often immigrants from across the globe come with protective factors, or otherwise known as behaviors that promote health. Often the ways foods are prepared and ingredients used are all local, but more importantly, they are super healthy. Once different groups come here, they lose these traditions, and sometimes end up eating really unhealthy fast food, simply because that is what is around, cheap and available. Bourdain does show there are other ways to healthy eating, that help to decrease obesity and show alternatives to the unhealthy food preparation techniques commonly used here in the US.


text:
Part 1- gaining unlock token
Overview: go to htcdev.com and unlock bootloader
Be sure you've turned off fast boot option in power menu; usb debugging should be on (settings -> developer options).
Go to http://www.htc.com/www/software/htc-sync-manager/[1] and install HTC SYNC. Alternatively, if you know what you're doing, you can install these drivers:
x86 http://www.mediafire.com/?qabo1tue2v1ky75 x64 http://www.mediafire.com/?8dl8s3l9mr6ggr9
Go on http://www.htcdev.com[4] and create yourself an account on HTCDEV.
Download these adb/fastboot files: http://devhost.xda-developers.com/RvD
Make a new folder anywhere. We'll use C:/fastboot as an example.
Extract the zip downloaded to the new folder
Go Here http://www.htcdev.com/bootloader/[6] and select "All Other Supported Models" and "then begin unlock bootloader" (check the boxes, click proceed, all that good stuff). YOU CAN IGNORE THE DIRECTIONS THAT THEY TELL YOU (and follow this guide instead).
Power off your phone. Power your phone on by holding power and volume down.
Highlight 'Fastboot' the volume buttons then press power to "select".
Plug your phone into your PC and open a Command Prompt. (windows XP - Click Start > Run > type CMD in box then press OK; Windows 7 - Click Start > type CMD in search box then press Enter) Change directory to your folder where we put fastboot files by typing cd c:\fastboot for example.*
*Alternatively, you can just hold down shift and right click in the folder and select "open command window here". Neat huh?
Type this into your command prompt window: fastboot oem get_identifier_token
Select & copy the text as per step 9 on the HTCDev website
Paste your identifier token into the box at the bottom and submit
You Will Very Shortly Receive an email from HTCDev with a link to the second part of the instructions and your "Unlock_code.bin" attached
Download the "Unlock_code.bin" from the email and save it to the same folder that we extracted fastboot files
Type this into your command prompt window: fastboot flash unlocktoken Unlock_code.bin
The Display Will change on your phone, press Vol+ to accept and power to confirm.
Part 2
Overview: flash your recovery. Boot into recovery. Turn phone off if it boots into OS. Boot into back into recovery. You're done!
Download a recovery:
TWRP (the one I use): http://forum.xda-developers.com/show....php?t=2173870
CWM 2: http://forum.xda-developers.com/show....php?t=2172979
CWM: http://forum.xda-developers.com/show....php?t=2173863
Place the Recovery file to the folder where the fastboot.exe is.
Same thing as above- boot (volume down + power) into the bootloader and highlight 'Fastboot' the volume buttons then press power to "select".
Do the same thing as with the command prompt above. This time, however, you'll be typing:
fastboot flash recovery "name_of_the_recovery.img"
For example:
fastboot flash recovery openrecovery-twrp-184.108.40.206-m7.img
then type:
fastboot erase cache
From the menu, boot into recovery (use volume to move up and down, power to select). The phone might boot to the OS instead of recovery, don't worry!
Turn off phone then turn on (while holding volume down) to boot back into the bootloader.
TAMPERED shows up, boot into recovery and now your recovery should be working!
Part 3- obtaining root
Overview: flash a super tool
Download a super user tool for root:
SuperSU (I use this one): http://forum.xda-developers.com/show....php?t=1538053
SuperUser: http://download.clockworkmod.com/sup.../superuser.zip
Alternatively, download this: http://forum.xda-developers.com/show....php?t=2252959. This is a stock rooted rom for ATT. If you download and flash this instead of the super user tool, you're done. (This rom includes super user) Or you can download a custom rom such as this one: http://forum.xda-developers.com/show....php?t=2183023
Turn on your phone again (and disable usb debugging) and connect to computer, copy the .zip super user tool to a location you remember ON the phone.
Flash it with the Recovery: Power off your device and then hold the VOL DOWN + Power to boot into the Bootloader Navigate with VOL and Power to Recovery Now flash the .zip:
- install zip from sdcard
- choose zip from sdcard
- select the downloaded SuperSU/SuperUser zip file and flash it
- Reboot now
You're not out of the woods yet! The stock kernel is system write protected, so you still can't modify it (changes won't "stick"). You'll have to flash a custom rom or a kernel if you want stock instead.
I recommend these kernels: http://forum.xda-developers.com/show....php?t=2255900 or http://forum.xda-developers.com/show...highlight=menu
Download it.
Installing custom rom/kernel ("flashing a rom")
Overview: Download Rom, boot into recovery and wipe and then flash.
According to Shenye, even though your device is s-on, you can still flash boot now. So just do this:
Turn on your phone again (and disable usb debugging) and connect to computer, copy the .zip kernel/cutom rom to a location you remember ON the phone.
Flash it with the Recovery: Power off your device and then hold the VOL DOWN + Power to boot into the Bootloader Navigate with VOL and Power to Recovery Now flash the .zip:
- install zip from sdcard
- choose zip from sdcard
- select the downloaded SuperSU/SuperUser zip file and flash it
- Reboot now


text:
Harwood House Stansted B&B has always been committed to providing the most comfortable stay for our guests. While we are honoured to have received 4 stars from the AA hotel accreditation scheme and we are rated the number one B&B in Great Dunmow on TripAdvisor, we are always looking for new ways to make Harwood House a place that our patrons remember fondly. We've recently made several updates to our rooms that we hope enhance the experience of our guests and travellers through Stansted.
Refurbished Rooms at Harwood House B&B
Our Deluxe Rooms feature beautiful Laura Ashley wallpapers and fabrics, oversized padded headboards, an iPod dock with speakers and a radio, ghost chairs, fluffy new bath sheet-sized towels, Cole & Lewis toiletries, plush throws with co-ordinating scatter cushions, magazines, and fresh, home-made biscuits. Combine all of this with our park and fly service, and travellers through Stansted have a fabulous place to stay.
A Stansted B&B With Parking
In addition to our refurbished rooms, Harwood House Stansted B&B offers a convenient and hassle free way to get to and from the airport. Staying even one night with us allows you to take advantage of our personalised park and fly service. As our guest, you can leave your car with us while you travel and we'll take care of getting you to the airport or anywhere in the area that you need to go. When you are ready to come back, Ian, proprietor, chef and licensed taxi driver, will be there to transport you back to Harwood House where you can stay another night or simply pick up your car and be on your way. We offer a bespoke service rather than hourly shuttles to and from Stansted; Ian will pick you up and drop you off whenever is most convenient for you, day or night. No extra waiting so you can enjoy your stay as long as possible.
If you are looking for a B&B near Stansted with parking, Harwood House has beautifully finished, clean, comfy rooms and a convenient, worry-free park and fly service to help provide you with peace of mind when you travel through Great Dunmow. You can book your stay online or give us a ring.


text:
Screen printing is a great method for bulk printing t-shirts, when using larger designs. Screen printed t-shirts are washable and can maintain the print quality for the longer period of time. Although digital printing on the t-shirt has become popular recently but screen printing is the more reliable method to get a t-shirt printed.
Many people confuse this method with the heat transfer print or the thermal prints. Thermal prints do not provide the long-term printing quality so they are not as good as screen printing method. The cost of screen printing depends on the colours used while printing as each new colour is added using a different screen.
It is amazing to see the value of screen printing even in the digital era. In the digital era where picture talks graphically and have great influence on the world, the traditional printing process should not be taken for granted.
The colour of the product and the design printed is very important to enhance the quality of the print. It is better to opt for the light colour as it is easy to print on them. While selecting the darker colour can increase the cost of the printing as the white base is required before starting the printing process.
Screen printing has its own advantage for the customer as well as the printer.
- Every single print is different and unique as it is hand pulled.
- The Ink surfaces crisply on the t-shirt which gives it a lovely demonstrative finish increasing the quality of the print.
- You can try to push the boundaries of screen printing by colour overlapping. Create more colours in a design without spending extra.
- No pressure to get the perfect design in the first try. Making mistakes is inevitable and it is fun to experiment with different styles.
- Getting messy can be fun too. It's lovely to wear clothes printed with different colours daily.
- Gym not needed! It's a great workout technique to get toned arms and washboard abs.
- Team-work can solve any puzzle while printing.
- Output depends entirely on the input. If you have taken your time in preparation than the output will be striking.
- It is astonishing to see the computerized image coming back to life.
- It provides long-lasting and high-quality results which cannot be washed out easily.
- It is very versatile in nature. It can accommodate a wide range of materials which also includes foam board and metal.
- It is not limited by size and shape which helps in printing distinctive images on mugs and bottles.
- It is easy to get the large volume of products printed easily using screen-printing.
- In many cases, the quality of screen printing is much better than the digital orienting.
- Screen printing fine tunes the image and enhances the all the colours making the print vibrant.
- It is advantageous for the fine line pictures and small texts.
- Screen printing is economical considering the fast, simple and bulk production.
There are plenty of marketing techniques to promote the special cause or the company. Screen printing t-shirts are a great branding option to print logos within the practical budget. While printing the t-shirt with the logo you are promoting your company. There are many effective marketing possibilities using screen printing.
- People pleasing designs
There is a range of t-shirt designs available in the market with brainstorming ideas, words, and feelings which are incorporated on them using screen printing.
- Options are affordable
Screen printing not only provides the great print but is also budget friendly. The price gets even well if you limit the colour used, the number of areas the design is to be done and for the bulk order of printed t-shirt.
- Out of the crowd
The t-shirt people wear is indirect promotion for your company. The custom made t-shirt will make your company stand out of the crowd and can increase your market value.
- Brand the business
A well-designed and trendy t-shirt can convert the companies name into a household name. The printed t-shirt can become so popular which can be the additional income for your company.
The printed custom t-shirt can also be used for different purpose apart from business marketing.
- Customer appreciation: Be the smart businessman and take care of your customers.
- Retreats: Remember the team-building spirit even after the retreat is over.
- Family reunion: Show the harmony with the family crest and your name during reunions.
- Volunteers: Using the printed and same t-shirt while volunteering can help in easy identification.
- Social events: Announce a good cause and celebrate the event for the special cause.
- Teams: Helps in cultivating team spirit and unity by using the same printed t-shirt.
There is always a reason to wear the custom printed t-shirt. The printing service depends on the company you will hire so choose wisely.


text:
Amid negotiations between the Holy See and China's Communist government over the appointment of bishops, Pope Francis has asked the nation's Catholics to remain "open to encounter and dialogue."
On May 24, which Pope Benedict declared a day of prayer for China's Catholics, "we will all be united spiritually to the Catholic faithful of China, on the feast of the Blessed Virgin Mary Help of Christians, venerated at the Sheshan Shrine at Shanghai," Pope Francis said to the faithful following his May 21 Regina Coeli address.
"To Chinese Catholics I say: let us raise our gaze to Mary Our Mother, so that she may help us to discern the will of God regarding the concrete path of the Church in China and support us in accepting her plan of love with generosity," the Pope continued, adding:
Mary encourages us to offer our personal contribution towards communion among believers and for the harmony of the society as a whole. Let us not forget to bear witness to faith with prayer and with love, always remaining open to encounter and dialogue.


text:
- Linda Morrissey- Dallas, Tx
Teresa Dermody-Reno, NV
"You truly inspire me to be a better version of me and in this moment I have happiness and joy in knowing that I am unconditionally loved by you and me; it centers me. I am smiling."
Barb Heite- Phoenix, AZ
"I was close to being a Master at being a victim. I reflexively blamed anyone and anything I could for my life's circumstances. I criticized the way others did things, yet felt profoundly wounded if others did not accept me as I was. I didn't know what was wrong, what I was doing wrong, or why I was so depressed - and don't ask me to admit that either!! "I'm ok." I got a lot of help from the members of this community, leaning into them when the going got tough. I learned I could tell them truths about myself, and they did not run away. In fact, they still offered me love. And in this way, I began to trust that I really was worthy of being loved, even in my behaviors. Thank you all for being a constant support to me. With much love and gratitude!"
Suzanne-Phoenix, AZ


text: You Know i was sittin here the other day bored as a monkey in straight jacket and i thought im gonna mess around with my phone a little. It was the first time in a long time i had recustomized looked for new apps and played around with the layout of my find phone. I think some of us. Especially root users forget the amazing capabilities of these devices we have. For months i had done nothing different with my phone, but play games, listen to music, check email, use navigation, call and text, BUT YOU KNOW sometimes we forget the awesome customizable features;widgets, banners,clocks, cyanogen mod is sick b/c u can choose ur own colors for everything. So don't forget how cool ur phone is and be thankful u have it . I <3 my Droid


text:
Somerset Dental Group
Dentist in Glastonbury, CT See Services
Patient Satisfaction
Recent Patient Reviews
Dr Hagopian n his team are incredible!!! I am extremely pleased with the work done and their treatment. Excellent customer service!!!
I've been a patient since I was 13 years old. Great staff, they're like family. Now, my Husband and children are patients as well. We recieve great care on every visit.
Services we provide
At Somerset Dental Group we strive to provide our patients with the best and most complete dental care. Our doctors and staff frequently attend continuing education seminars to learn the latest dental techniques. Here are some of the services we provide
Payment Forms
We offer a number of convenient payment options for our patients which make it easy to afford any care you may need.
American Express, Care Credit, Cash, Check, Discover, Traveler's Check, Visa
Credit Card
Payment Options
- Debit Card
Insurance view accepted carriers here
Insurance carriers
Languages Spoken
- English
- German


text:
We have companies that will paint your house numbers on your curb, but I thought that they charged too much for something that I could do myself and do prettier!
Here's what you will need to complete this project.
Blue Painters Tape
4" or Larger Number Stencils
Decorative Stencil of Your Choice
Can of White Spray Paint
Stencil Brushes (1 for each color)
Craft Paint in Desired Colors
Paper Towel (to off load paint from stencil brush)
Paper Plate (to hold craft paint)
Decorative Paint Brushes (if painting design and numbers by hand)
Here's the steps I took to do this simple safety project:
1. Wash your curb with a scrub brush and rinse. You won't believe the amount of dirt.
2. You can do this project one of two ways. Either buy the 4" number stencils at an office supply store or print up letters in the desired font and size on your computer and use transfer paper to transfer to curb and paint by hand. I went the stencil route since it is 110 degrees outside in Arizona and I wanted to get this done as quickly as possible.
3. If going the stencil route, tape the number stencils together and then tape the decorative part of the stencil to the left. You need this all together so you can figure out how big your square paper template needs to be. If you are painting by hand, print out your decorative design out on paper and tape together to figure the size you need.
6. Lay your decorative stencil and number stencils down and tape using blue painters tape. Stencil using a dry brush stencil technique. It does not take a lot of paint on a stencil brush to get the job done. Your brush should have just enough paint on it so that when you pounce on a paper towel, you get a powdery effect. If you use too much paint, paint will seep under the stencil and look messy. Better do to a light coat of paint and build up your color rather than over do it. If you are using a pattern instead of stencils, transfer your design with transfer paper and paint by hand with decorative paint brushes. Here's what it looked like while I was stenciling.


text:
Weaver, Mark
- June 2nd, 2010
- in
Dr. Mark L. Weaver is an Associate Professor in the Department of Metallurgical and Materials Engineering. He received his Ph.D. from the University of Florida, Gainesville, FL in 1995. From 1995 until 1997 he served as a Posdoctoral Research Associate at the Center for Nonlinear and Nonequilibrium Aeroscience at Florida A&M University (FAMU) and the Center for Materials Research and Technology at Florida State University (FSU), Tallahassee, FL, where he studied texture evolution in magnetoresistive thin film materials. In 1996 he was additionally appointed as a researcher in the Department of Mechanical Engineering at the FAMU-FSU College of Engineering, Tallahassee, FL. His research interests include microstructural characterization, texture, mechanical properties, and tribology of bulk and thin film materials. Dr. Weaver has authored or co-authored more than 20 technical publications.


text:
Halliday Top Results Pack
Following the release of James Halliday's 2019 Wine Companion results, we're pleased to put together the Halliday Top Results pack - an exclusive offer for our Cellar Club members! The 6-pack includes the following wines:
2 x Clairault Estate Chardonnay 2016
"A wine of rare purity, intensity and length"
Exclusive pre-release!
2 x Clairault Margaret River Cabernet Sauvignon 2016
"A lovely Margaret River cabernet"
Current release
2 x Streicker Bridgeland Block Sauvignon Blanc Semillon 2016
"Mouthwatering stream of flavours"
Exclusive pre-release!
Only $168 + complimentary freight!
In Stock


text:
Cloverdale Post Office (historical) ( DuPage )
Illinois : Flag of State
Cloverdale Post Office (historical) is a place of kind Post Office belonging to the County of ( DuPage ).
The closest populated place is that of Cloverdale that is0.00 miles far from Cloverdale Post Office (historical).
Cloverdale Post Office (historical) is also 5.23 miles far from the closest airport or heliport, the Van Kampen Heliport .
The weather forecasting are available for the town of Carol Stream , that is 3.40 miles far from Cloverdale Post Office (historical) .
The Zip Code of Cloverdale Post Office (historical) is 60116.
Besides Cloverdale Post Office (historical) in the County of ( DuPage ) there are the following places of kind Post Office . These are reported in what follows in alphabetical order:
Addison Post Office - Big Woods Post Office (historical) - Bloomingdale Post Office - Clarendon Hills Post Office - Downers Grove Post Office - Glen Ellyn Post Office - Lombard Post Office - Lombard Post Office - Naperville Post Office - Roselle Post Office - Warrenville Post Office - Westmont Post Office - Wheaton Post Office - Winfield Post Office - Woodridge Post Office .
Where to stay: Hotels and other Accommodation Cloverdale Post Office (historical)
Please find in what follows the full listing of the Hotels, Bed & Breakfasts and other accommodation available in Cloverdale Post Office (historical).
A lot of pictures and fully detailed descriptions are available for the Hotels, Bed & Breakfasts and other accommodation, along with the ratings assigned by the guest of the same Hotels. The ratings are divided by age, sex and much more.
Illinois : Emblem of State
- Capital : Springfield
- Inhabitants : Illinoisan (Flatlander, Illini, Illinoyer)
- State's Motto : State sovereignty, national union
- English translation : State sovereignty, national union
Map and road map of Cloverdale Post Office (historical)
View the interactive maps of Cloverdale Post Office (historical) and get road maps, satellite maps and much more. The maps cover a wide area centered on Cloverdale Post Office (historical) .
On each map are available: a selector scale, on the bottom right of the map,a menu for choosing different views of the same map, placed in the upper left corner of the map, a free text search field for locating any business activity within the map itself, placed at the top center of the map.
The videos about Cloverdale Post Office (historical)
It is proposed a first video: clicking on the PLAY button the video will start. Inside the video window there are several commands and a Playlist button. Press the Playlist button to access the complete listing of available videos, along with their titles. It will be sufficient to scroll through the list using the cursor to select any of the videos. You can use the << and >> keys to scroll through the videos. Each video can be displayed in full screen.