24
Using Apache Portable Runtime (APR) To make cross-platform development easier

Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

  • Upload
    others

  • View
    14

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Using Apache Portable Runtime (APR)

To make cross-platform development easier

Page 2: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Bruce Greenblatt Sr. Principal Software Engineer Symantec Information Management Division Data Insight http://www.symantec.com/data-insight [email protected]

Page 3: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

How to Support Multiple Target OS Platforms?

• As a developer, sometimes we have to make our code work on more than one OS. Usually just these two for me: – Linux – Windows

• What techniques are available to help? The two most popular techniques seem to be: – Write on Windows and laugh as the poor Linux

developers have to port your native code. – Write on Linux and laugh as the poor Windows

developers have to port your native code.

Page 4: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

What is APR

• A set of C Language APIs that are implemented on Linux and Windows

• The APIs provide access to OS primitives and other useful functionality, e.g. – Synchronization and Multithreading

– File System

– Time Functions

– Hashing

– Memory Mapped

– Command Line Parsing

Page 5: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

What is APR (cont)

• Used by Apache Web Server implementers to ease porting to multiple platforms

• It provides a consistent interface to underlying platform-specific functionality

• It’s FREE to use and distribute • Source code is available • My team uses APR on:

– Windows Servers: 2003, 2008, 2012 32 and 64-bit – Windows Desktops: 7 – Linux:

• Centos (5 and 6) • RHEL 5 • Ubuntu

Page 6: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Who Should Use APR?

• Will you have to develop code that runs on Linux and Windows? – If so, then you should use APR.

• Will you have to develop code that runs on multiple versions of Linux? – If so, then you should probably use APR.

• Are you a Linux developer and are worried that the sales team will tell you the exciting news about the big deal they just made that requires a Linux version? – If so, then you should probably use APR.

• Do you have to work on Windows but are more comfortable with Linux tools? – If so, then you could use APR and develop and debug on Linux.

Page 7: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Approach

• Don’t use native APIs. • Write to APR APIs where available • Compile your code and link with APR on the

platforms it supports • Many APR calls look very similar to native Linux

calls, but are prefixed by “apr_”. – apr_atoi64 instead of atoi64 – apr_file_open instead of fopen

• All APIs implemented on each platform – There aren’t any “not implemented yet” stubs!

Page 8: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Keys

• Source code available – Home page is: http://apr.apache.org/ – Licensed un Apache License 2.0 – Build environment for Windows and Linux – I use cygwin and MSVC for Windows builds, and gcc for Linux

• Great Documentation available: – http://apr.apache.org/docs/apr/1.4/modules.html – http://apr.apache.org/mailing-lists.html

• Compiles to native APIs – There’s no middleware system running along with your program – There’s no APR Virtual Machine

Page 9: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Debugging APR

• Since you get the source code, if you compile in debug mode

– You can step into APR code

– You can set breakpoints, etc. inside APR code

– You can look at APR internal data structures

• This is a major advantage over some previously used proprietary libraries, where this was not available

Page 10: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Initialization and Termination

• Before making apr calls, the library must be initialized, and a memory pool allocated – apr_initialize();

– apr_pool_t *mp = NULL;

– status = apr_pool_create(&mp, NULL);

• When done, the memory pool is destroyed, and the library is shutdown: – apr_pool_destroy(mp);

– apr_terminate();

Page 11: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Memory Pools

• Mainly used by APR for internal memory allocation.

• Theoretically, they can be used for your own memory too (but I never have).

• So, many apr functions take an apr_pool_t structure as a parameter.

Page 12: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Simple program

apr_pool_t *mp = NULL;

apr_time_t time1 = 0, time2 = 0;

apr_initialize();

apr_pool_create(&mp, NULL);

time1 = apr_time_now();

time1 = apr_time_sec(time1);

/* do some stuff */

time2 = apr_time_now();

time2 = apr_time_sec(time2);

printf(“Did stuff in %"APR_TIME_T_FMT" seconds.\n", time2 – time1);

apr_sleep(1000000);

apr_pool_destroy(mp);

apr_terminate();

Apr_time_t is a 64 bit number representing the number of seconds since epoch start (i.e. midnight Jan 1, 1970). Apr_sleep always sleeps for the specified number of microseconds. Let’s look at the implementation on Linux and Windows to see the difference.

Page 13: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Windows apr_time_now()

APR_DECLARE(apr_time_t) apr_time_now(void)

{

LONGLONG aprtime = 0;

FILETIME time;

SYSTEMTIME st;

GetSystemTime(&st);

SystemTimeToFileTime(&st, &time);

FileTimeToAprTime(&aprtime, &time);

return aprtime;

}

Page 14: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Linux apr_time_now()

APR_DECLARE(apr_time_t) apr_time_now(void)

{

struct timeval tv;

gettimeofday(&tv, NULL);

return tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec;

}

Page 15: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Implementation Differences

• Notice both Linux and Windows have the same behavior

• It’s important to look at the implementation on each platform to understand if there are any differences in the behavior

• It appeared to me in some cases (especially process synchronization) that the behavior on Windows vs Linux was different

Page 16: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Atomic Operations

• Used to update shared integers without locking

• Always call apr_atomic_init(mp); before using any APR atomic API call

• Calls are available to read, set and increment, decrement and add 32 bit integers

– apr_atomic_inc32(&i); // increments i

– j = apr_atomic_read32(&i); // stores the value of I in j

– apr_atomic_set32(&i, j); //updates the value of i with j

Page 17: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Atomic Operations (cont)

• Consider apr_atomic_inc32

– Windows implementation uses a platform call InterlockedIncrement

– Some *nix implementations use Native APIs, some ia32 based implementations use assembly.

Page 18: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Shared Memory

• Allows one process to create a memory segment and share it with another process (or processes).

• A simple way of allowing multiple processes to communicate – E.g. A process may create a shared memory area to

store it’s current “state”, which may include certain counters, etc.

– Other processes will then access the shared memory to see how that process is doing.

• Usually requires synchronization, e.g. proc mutex, if readers and writers are involved

Page 19: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Shared Memory Example apr_pool_t *mp = NULL;

apr_shm_t *ctrs = NULL;

apr_proc_mutex_t *mutex_ctrs = NULL;

apr_status_t status = APR_SUCCESS;

apr_initialize();

status = apr_pool_create(&mp, NULL);

status = apr_proc_mutex_create(&mutex__ctrs, MTX_FILENAME,

APR_LOCK_DEFAULT, mp);

status = apr_shm_attach(&shm_netapp_ctrs, shmem_path, mp);

apr_proc_mutex_lock(mutex_ctrs);

p = (ctr_info_t *) apr_shm_baseaddr_get(shm_netapp_ctrs);

while (p && p->dev_id !=0) {

apr_ctime(apr_str, p->timestamp);

printf("id: %d\t latency: %d microseconds\t timestamp%s\n"

p->id, p->latency, apr_str);

i++;

if (i >= MAX_DEVICES) {

break;

}

p++;

}

apr_proc_mutex_unlock(mutex_netapp_ctrs);

apr_proc_mutex_destroy(mutex_netapp_ctrs);

status = apr_shm_detach(shm_netapp_ctrs);

apr_pool_destroy(mp);

apr_terminate();

Page 20: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

Shared Memory Implementation

• On Windows use CreateFileMapping and MapViewOfFile

• On Linux use mmap, shmget, etc. Open APIs.

Page 21: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Multithreading support

• APR supports creating and exiting threads much like pthreads.

• apr_thread_create to start a thread

– You pass in the function to start the thread in

– The data you want to pass in to the thread

– An APR memory pool

• apr_thread_exit to terminate the thread

Page 22: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Hash Tables

• Create a hash table using one of two APIs: – hash = apr_hash_make(mp); – hash = apr_hash_make_custom(mp, callback_hash_function);

• Use the second version if you want to provide your own hash function and don’t want to use APR’s default hash function.

• Hash table lookup using apr_hash_get(hash, key_string, keylen); – keylen is usually = APR_HASH_KEY_STRING

• Hash table insert using apr_hash_set(hash, key_string, keylen, val); – Val is a void * – keylen is usually = APR_HASH_KEY_STRING

Page 23: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Hash Tables (cont)

• Clean up hash tables by removing all the rows, and then calling apr_hash_clear();

apr_hash_index_t *hi = 0;

char *key = 0;

apr_ssize_t keylen = 0;

if (hash) {

hi = apr_hash_first(mp, hash);

while (hi) {

apr_hash_this(hi,(const void**) &key, &keylen,

(void**) &e);

if (e) {

free(e->field1);

free(e->field2);

free(e);

e = NULL;

}

hi = apr_hash_next(hi);

}

apr_hash_clear(hash);

hash = NULL;

}

Page 24: Using Apache Portable Runtime (APR)files.meetup.com/1590495/Using Apache Portable Runtime (APR).pdf•Used by Apache Web Server implementers to ease porting to multiple platforms •It

APR Modules

• Internal Memory Allocation • Atomic Operations • Dynamic Object Handling • Functions for manipulating the

environment • Error Codes

– APR Error Space – APR Error Values – Status Value Tests

• File Information – File Permissions flags – Stat Functions – Directory Manipulation Functions – Filepath Manipulation Functions

• File I/O Handling Functions – File Open Flags/Routines – File Seek Flags – File Attribute Flags – {_full} max iovec size – File Lock Types

• Filename Matching Functions • Miscellaneous library routines • Command Argument Parsing • Global Locking Routines

• Hash Tables • General Purpose Library Routines • MMAP (Memory Map) Routines • Network Routines

– Socket option definitions – IP Protocol Definitions for use

when creating sockets – IP Multicast

• Poll Routines • Memory Pool Functions

– Pool Cleanup Functions – Pool Debugging functions.

• Portability Routines – Thread portability Routines – DSO (Dynamic Loading) Portability

Routines

• Process Locking Routines • Random Functions • Ring Macro Implementations • Shared Memory Routines • Signal Handling • String routines

– snprintf implementations

• Internal APR support functions

• Table and Array Functions • Condition Variable Routines • Thread Mutex Routines • Threads and Process Functions

– Other Child Flags

• Reader/Writer Lock Routines • Time Routines • User and Group ID Services • Library initialization and

termination • ctype functions (e.g. apr_islower)