The first step in converting the project from synchronous to asynchronous operation is to implement a class which contains all the inputs and outputs of a single calculation. It will be used in several ways:
The class contains three sets of data:
The signature of the existing calculation function is:
extern "C"
int eval_avg_opt
(
    int     put,
    double  spot,
    double  sigma,
    double  loan,
    double  discount,
    double  div_yield,
    long    value_date,
    long    maturity,
    long    avg_in_count,
    long    *avg_in_dates,
    long    avg_out_count,
    long    *avg_out_dates,
    long    iters,
    double* result,
    char*   err_buf,
    int     err_buf_size
);
		The data members of the AvgOptData class will therefore be as follows:
class AvgOptData
{
    // Data members
public:
    // Inputs
    int                 put;
    double              spot;
    double              sigma;
    double              loan;
    double              discount;
    double              div_yield;
    long                value_date;
    long                maturity;
    std::vector<long>   avg_in_dates;
    std::vector<long>   avg_out_dates;
    long                iters;
    // Outputs
    double              result;
    char                err_buf[512];
    int                 rc;
    bool                done;
    ...
};
		The class contains three functions and an overloaded operator:
class AvgOptData
{
    ...
    // Constructor
    AvgOptData(int put_, double spot_, double sigma_, double loan_, 
        double discount_, double div_yield_, long value_date_, 
	    long maturity_, const std::vector<long>& avg_in_dates_, 
	    const std::vector<long>& avg_out_dates_, long iters_) 
    {
        // Initialize output
        ... 
        // Copy inputs
        ... 
    }
    // Evaluation
    void Evaluate()
    {
        rc = eval_avg_opt(put ? 1 : 0, spot, sigma, loan, discount, 
            div_yield, value_date, maturity, avg_in_dates.size(), 
            avg_in_dates.size() ? &avg_in_dates[0] : 0, 
            avg_out_dates.size(), 
            avg_out_dates.size() ? &avg_out_dates[0] : 0, 
            iters, &result, err_buf, sizeof(err_buf));
        done = true;
    }
    // Comparison
    static int Compare(const AvgOptData& x, const AvgOptData& y)
    {
        // Compare only inputs
        ...
    }
    bool operator<(const AvgOptData& c) const 
    { 
        return Compare(*this, c) < 0; 
    }
};
		The methods are used as follows:
The AvgOptData object is used by the main thread and by a worker thread. It is therefore important to make sure that there are no thread conflicts when writing and reading the object.
There are 4 points at which the object is accessed: