Locking Map Data Source

Operating system requirements: iOS 5.0 or later.

Mobile device: iPad

Description

This example describes locking of map data source. After starting the example the following operations are executed:

Source Code

Executing the example requires to place the following code in the body of the executeExample method of the ViewController class (see the Displaying of Express Report section):

// Get express report delegate
EAReportDelegateImpl *delegate = [m_controller delegate];
// Get map data source
MapDataViewDatasource *delegateMapDatasource = [delegate mapDatasource];
// Get metric dimension, observation object dimension, and dimension used to build a timeline, from map data source
SPPLDimension metricsDimension = [delegateMapDatasource metricsDimension_Map];
SPPLDimension topoDimension = [delegateMapDatasource observationDimension_Map];
SPPLDimension calendarDimension = [delegateMapDatasource timelineDimension_Map];
// Set obtained express report dimensions
m_olapReport->putDimensionToFixed(metricsDimension);
m_olapReport->putDimensionToLeft(topoDimension);
m_olapReport->putDimensionToTop(calendarDimension);
m_olapReport->setMetrics(metricsDimension->id());
m_olapReport->setObjectives(topoDimension->id());
m_olapReport->setTimeline(calendarDimension->id());
// Create a pivot object for building data tables
SPPLPivot pivot = PPLPivot::pivot(m_olapReport);
// Create a data table
SPPLPivotTable pivotTable = PPLPivotTable::pivotTable(pivot);
// Create a new map data source
MapDataViewDatasource *mapDatasource = [[MapDataViewDatasource alloc] initWithPivotTable:pivotTable olapReport:m_olapReport withFullTopoSelection:YES];
// Create a new program execution thread
NSThread *thread1 =[[NSThread alloc] initWithTarget:self selector:@selector(thread1Run:) object:mapDatasource];
// Set low priority for new thread
[thread1 setThreadPriority: 0.1];
// Start new program execution thread
[thread1 start];

It is also required to add the following methods with their implementation in the ViewController class:

// Executes operations of first program execution thread
- (void) thread1Run: (MapDataViewDatasource *) mapDatasource {
    NSLog(@"Data source is locked in first thread");
    // Create a new program execution thread
    NSThread *thread2 =[[NSThread alloc] initWithTarget:self selector:@selector(thread2Run:) object:mapDatasource];
    // Set high priority for new thread
    [thread2 setThreadPriority: 1.0];
    // Start new program execution thread
    [thread2 start];
    // Get metric dimension name dictionary
    // If data source is locked, thread execution is paused on addressing map data source     NSDictionary *metricsDimensionsKeys = [mapDatasource metricsDimensionsKeys];     NSLog(@"Data source is unlocked in first thread"); }
// Executes operations of second program execution thread - (void) thread2Run: (MapDataViewDatasource *) mapDatasource {     NSLog(@"Data source is locked in second thread");     // Get metric dimension name dictionary
    // If data source is locked, thread execution is paused on addressing map data source     NSDictionary *metricsDimensionsKeys = [mapDatasource metricsDimensionsKeys];     NSLog(@"Data source is unlocked in second thread"); }

After executing the example the development environment console displays messages, which can be used to determine order of program operation execution:

Data source is locked in first thread

Data source is locked in second thread

Data source is unlocked in first thread

Data source is unlocked in second thread

 

Logic of thread operation order is violated, because the second program execution thread is called inside the first thread with a higher priority. To avoid such situations, use thread locking. Replace code in the thread1Run: method in the ViewController class with the following code:

// Lock map data source
[[mapDatasource updateLock] lock];
NSLog(@"Data source is locked in first thread");
// Create a new program execution thread
NSThread *thread2 =[[NSThread alloc] initWithTarget:self selector:@selector(thread2Run:) object:mapDatasource];
// Set high priority for new thread
[thread2 setThreadPriority: 1.0];
// Start new program execution thread
[thread2 start];
// Get metric dimension name dictionary
// If data source is locked, thread execution is paused on addressing map data source NSDictionary *metricsDimensionsKeys = [mapDatasource metricsDimensionsKeys]; NSLog(@"Data source is unlocked in first thread"); // Unlock map data source [[mapDatasource updateLock] unlock];

It is also required to replace code in the thread2Run: method in the ViewController class with the following code:

// Lock map data source
[[mapDatasource updateLock] lock];
NSLog(@"Data source is locked in second thread");
// Get metric dimension name dictionary
// If data source is locked, thread execution is paused on addressing map data source NSDictionary *metricsDimensionsKeys = [mapDatasource metricsDimensionsKeys]; NSLog(@"Data source is unlocked in second thread"); // Unlock map data source [[mapDatasource updateLock] unlock];

After executing the updated example the development environment console displays correct order of program execution:

Data source is locked in first thread

Data source is unlocked in first thread

Data source is locked in second thread

Data source is unlocked in second thread

 

The second program execution thread is called inside the first thread with a higher priority, but as the data source is locked in the first thread, the repeated locking results in pausing the thread and adding a queue of threads waiting for data source unlocking.

See also:

Examples of Component Use