2012年1月28日 星期六

[PThread] condition variable usage pattern

producer/consumer model. The return value for each pthread function call need to be checked too.

Producer:


while(/* condition for producer to contintue */)
{
pthread_mutex_lock(&mutex);

// do something for producer

// the order of the two following call is not important
// unlock before signal may more efficient than signal before unlock
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}

Consumer:


while(/* condition for consumer to continue */)
{
// must contain lock before calling condition wait
pthread_mutex_lock(&mutex);

// the condition wait need to be recheck for
// 1. spurious wakeup
// 2. other thread can be waken early
while(/* condition to check for state not valid */)
{
s = pthread_cond_wait(&cond, &mutex);
}
// do consumer work, now under mutex protection
pthread_mutex_unlock(&mutex);
// some other work which don't need mutex
}

Spurious wakeup:
Some condition wait implementation can cause the thread to be waken up when no signal to the condition variable.
man pthreadconidsignal for further detail.

2012年1月15日 星期日

[TCP] some tuning options

The IPTOS_LOWDELAY keyword is most appropriate for low-delay networks such as LANs, while IPTOS_THROUGHPUT is for higher-latency WAN links. Your network may be configured differently, so it's possible that using the options might have the opposite effect.

The TCP_NODELAY option disables the Nagle algorithm.

If you have firewalls or other devices that keep state in your network, you may be interested in the SO_KEEPALIVE option, which turns on TCP keepalives.

$ netstat -d -i 2

Every 2 seconds, the status of the available interfaces is shown. In the example above, the RX-OK and TX-OKcolumns show that packets are flowing in and out. The errors, drops, and overruns are all 0 in both directions, showing that there has been no packet loss.


2012年1月9日 星期一

[C++] Exception-safe code



Some guide

Exception-safe definition:
- Basic
    invariants and no resource are leaked
- Strong
    operations has either completed successfully or throw exception leaving program
    state exactlyly as it was before the operation started
- No-throw
    operation will not emit an exception

Exception guide line:
- Throw by value
- Catch by reference
- no exception specification
                                                                                                                                                                                                           
* function can not template partial specialization

Some code example:

#include <iostream>     
void foo() throw ()
{                  
    // it will cause abort 
    // because it throw when the exception specification said NO
    throw(1);      
}                  
                   
void goo()         
{                  
    try {          
        int a = 1; 
        throw(1);  
    } catch(...) { 
        // this will cause abort too 
        // because you can not rethrow in catch statement
        throw;     
    }              
}                  
                   
/*                 
 * The following is the C API for C++ library pattern to handle exception
 */                
                   
int getReturnCodeFromException()
{                  
    try {          
        // rethrow 
        throw;     
    } catch(int a) 
    {              
        return -1; 
    } catch(double b)
    {              
        return -2; 
    }              
    // for each type of exception, you can create different return code
    // ...         
}                  
void cppAPI1()
{           
    throw (1);
}           
            
            
void cppAPI2()
{           
    throw (1.12);
}           
            
int cAPI1() 
{           
    try {   
        cppAPI1();
    } catch(...) {                           
        int rc = getReturnCodeFromException();
        return rc;
    }       
}           
            
int cAPI2() 
{           
    try {   
        cppAPI2();
    } catch(...) {                           
        int rc = getReturnCodeFromException();
        return rc;
    }       
}           
            
int main()  
{           
//    foo();
//    goo();
    std::cout << "cAPI1 rc = " << cAPI1() << std::endl;
    std::cout << "cAPI2 rc = " << cAPI2() << std::endl;
    return 0;
}                                
Reference http://exceptionsafecode.com/

2012年1月6日 星期五

[C++] dynamic_cast

You can use dynamic_cast to identify the type. Then you can do something different according to Derived class with the same Base class pointer.
Just a reminder, when you call destructor of derived class. The vtable pointer and RTTI is no longer exist.
As a result, you will get NULL at second dynamic_cast.
#include <iostream>
#include <cstdio>
#include <cstdlib>

class Base
{
public:
    Base():a(1){};
    ~Base(){};
    virtual void foo() {};
    int a;
};

class Derived : public Base
{
public:
    Derived(){};
    ~Derived(){};
    virtual void foo() {};
};

int main()
{
    void *p = malloc(sizeof(Derived));

    Base *base = new (p) Derived();
    Derived *d = dynamic_cast(base);
    if(d)
        std::cout << "cast ok!\n";     d->~Derived();
    Derived *dd = dynamic_cast(base);
    if(dd)
        std::cout << "cast ok!\n";
    else std::cout << "cast fail!\n";
    return 0;
}