userlibandfileserver/fileserver/sfile/sf_request.cpp
branchRCL_3
changeset 43 c1f20ce4abcf
parent 42 a179b74831c9
child 44 3e88ff8f41d5
equal deleted inserted replaced
42:a179b74831c9 43:c1f20ce4abcf
   972 //
   972 //
   973 // Process the message in post operation mode (handled by the current plugin)
   973 // Process the message in post operation mode (handled by the current plugin)
   974 //
   974 //
   975 	{
   975 	{
   976 	TInt err = KErrNone;
   976 	TInt err = KErrNone;
   977 	if(!iCurrentPlugin->IsPluginThread(*this))
   977 	if(!iCurrentPlugin->OriginatedFromPlugin(*this))
   978 		{
   978 		{
   979 		// The request hasn't come from this plugin so it's safe to dispatch		
   979 		// The request hasn't come from this plugin so it's safe to dispatch		
   980 		TFsPluginRequest request(this);
   980 		TFsPluginRequest request(this);
   981 		TRAPD(leaveValue, err = iCurrentPlugin->DoRequestL(request));
   981 		TRAPD(leaveValue, err = iCurrentPlugin->DoRequestL(request));
   982 		if(leaveValue != KErrNone)
   982 		if(leaveValue != KErrNone)
   995 			}
   995 			}
   996 		}
   996 		}
   997 	
   997 	
   998 	// Find the previous plugin in the chain and dispatch
   998 	// Find the previous plugin in the chain and dispatch
   999 	//  - If no more plugins are interested in this message, then complete
   999 	//  - If no more plugins are interested in this message, then complete
  1000 	FsPluginManager::PrevPlugin(iCurrentPlugin, this, ETrue);
  1000 	FsPluginManager::ReadLockChain();
       
  1001 	FsPluginManager::PrevPlugin(iCurrentPlugin, this);
  1001 	if(iCurrentPlugin == NULL)
  1002 	if(iCurrentPlugin == NULL)
  1002 		{
  1003 		{
       
  1004 	    FsPluginManager::UnlockChain();
  1003 		Complete(GetError());
  1005 		Complete(GetError());
  1004 		return;
  1006 		return;
  1005 		}
  1007 		}
  1006 
  1008 
  1007 	Dispatch();
  1009 	Dispatch();
       
  1010 	FsPluginManager::UnlockChain();
  1008 	return;
  1011 	return;
  1009 	}
  1012 	}
  1010 	
  1013 	
  1011 
  1014 
  1012 void CFsMessageRequest::ProcessPreOperation()
  1015 void CFsMessageRequest::ProcessPreOperation()
  1013 //
  1016 //
  1014 // Process the message in pre operation mode (handled by the current plugin)
  1017 // Process the message in pre operation mode (handled by the current plugin)
  1015 //
  1018 //
  1016 	{
  1019 	{
  1017 	TInt err = KErrNone;
  1020 	TInt err = KErrNone;
  1018 	if(!iCurrentPlugin->IsPluginThread(*this))
  1021 	if(!iCurrentPlugin->OriginatedFromPlugin(*this))
  1019 		{
  1022 		{
  1020 		// The request hasn't come from this plugin so it's safe to dispatch		
  1023 		// The request hasn't come from this plugin so it's safe to dispatch		
  1021 		TFsPluginRequest request(this);		
  1024 		TFsPluginRequest request(this);		
  1022 		TRAPD(leaveValue, err = iCurrentPlugin->DoRequestL(request));
  1025 		TRAPD(leaveValue, err = iCurrentPlugin->DoRequestL(request));
  1023 		__PLUGIN_PRINT1(_L("PLUGIN: CFsMessageRequest:: %x processed by plugin"), this);
  1026 		__PLUGIN_PRINT1(_L("PLUGIN: CFsMessageRequest:: %x processed by plugin"), this);
  1024 
  1027 
  1025 		if((iOperation->Function() == EFsDismountPlugin) && (err !=  KErrPermissionDenied))
  1028 		if((iOperation->Function() == EFsDismountPlugin) && (err !=  KErrPermissionDenied))
  1026 			{
  1029 			{
  1027 			TRAP(leaveValue, err = iOperation->DoRequestL(this));
  1030 		    err = KErrNone;
  1028 			}
  1031 			}
  1029 
  1032 
  1030 		if(leaveValue != KErrNone)
  1033 		if(leaveValue != KErrNone)
  1031 			{
  1034 			{
  1032 			Panic(KFsClient,leaveValue);
  1035 			Panic(KFsClient,leaveValue);
  1040 	if(err == KErrNone)
  1043 	if(err == KErrNone)
  1041 		{
  1044 		{
  1042 		// Find the next plugin in the chain and dispatch
  1045 		// Find the next plugin in the chain and dispatch
  1043 		//  - If no more plugins are interested in this message, 
  1046 		//  - If no more plugins are interested in this message, 
  1044 		//	  then Dispatch() will process the request in drive/main thread context.
  1047 		//	  then Dispatch() will process the request in drive/main thread context.
  1045 		FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1048 	    FsPluginManager::ReadLockChain();
       
  1049 		FsPluginManager::NextPlugin(iCurrentPlugin, this);
  1046 		if(iCurrentPlugin && IsPostOperation())
  1050 		if(iCurrentPlugin && IsPostOperation())
  1047 			SetPostOperation(EFalse);
  1051 			SetPostOperation(EFalse);
  1048 		Dispatch();
  1052 		Dispatch();
       
  1053 		FsPluginManager::UnlockChain();
  1049 		return;
  1054 		return;
  1050 		}
  1055 		}
  1051 	// KErrCompletion may be returned by the plugin to 
  1056 	// KErrCompletion may be returned by the plugin to 
  1052 	// indicate that it has process the message itself (do post-intercept)
  1057 	// indicate that it has process the message itself (do post-intercept)
  1053 	else if (err == KErrCompletion)
  1058 	else if (err == KErrCompletion)
  1054 		{
  1059 		{
  1055 		// Find the previous plugin in the chain and dispatch
  1060 		// Find the previous plugin in the chain and dispatch
  1056 		//  - If no more plugins are interested in this message, then complete
  1061 		//  - If no more plugins are interested in this message, then complete
  1057 		FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1062 	    FsPluginManager::ReadLockChain();
       
  1063 		FsPluginManager::PrevPlugin(iCurrentPlugin, this);
  1058 		if(iCurrentPlugin != NULL)
  1064 		if(iCurrentPlugin != NULL)
  1059 			{
  1065 			{
  1060 			SetPostOperation(ETrue);
  1066 			SetPostOperation(ETrue);
  1061 			err = KErrNone;
  1067 			err = KErrNone;
  1062 			Dispatch();
  1068 			Dispatch();
       
  1069 			FsPluginManager::UnlockChain();
  1063 			return;
  1070 			return;
  1064 			}
  1071 			}
  1065 		else
  1072 		else
  1066 			{
  1073 			{
  1067 			err = KErrNone;	
  1074 			err = KErrNone;	
  1068 			}
  1075 			}
       
  1076 		FsPluginManager::UnlockChain();
  1069 		}
  1077 		}
  1070 		
  1078 		
  1071 	Complete(err);
  1079 	Complete(err);
  1072 	return;
  1080 	return;
  1073 	}
  1081 	}
  1122 
  1130 
  1123 	// Start issuing the post-operation requests starting from the bottom of the chain
  1131 	// Start issuing the post-operation requests starting from the bottom of the chain
  1124 	iCurrentPlugin = NULL;
  1132 	iCurrentPlugin = NULL;
  1125 	if (PostInterceptEnabled())
  1133 	if (PostInterceptEnabled())
  1126 		{
  1134 		{
  1127 		FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1135 	    FsPluginManager::ReadLockChain();
  1128 		if(iCurrentPlugin && !iCurrentPlugin->IsPluginThread(*this))
  1136 		FsPluginManager::PrevPlugin(iCurrentPlugin, this);
       
  1137 		if(iCurrentPlugin && !iCurrentPlugin->OriginatedFromPlugin(*this))
  1129 			{
  1138 			{
  1130 			SetPostOperation(ETrue);
  1139 			SetPostOperation(ETrue);
  1131 			if (DispatchToPlugin())
  1140 			if (DispatchToPlugin())
       
  1141 			    {
       
  1142 		        FsPluginManager::UnlockChain();  
  1132 				return;
  1143 				return;
  1133 			}
  1144 			    }
       
  1145 			}
       
  1146 		FsPluginManager::UnlockChain();		
  1134 		}		
  1147 		}		
  1135 
  1148 
  1136 	Complete(GetError());
  1149 	Complete(GetError());
  1137 	return;
  1150 	return;
  1138 	}
  1151 	}
  1407 
  1420 
  1408 		// Start issuing the post-operation requests starting from the bottom of the chain
  1421 		// Start issuing the post-operation requests starting from the bottom of the chain
  1409 		iCurrentPlugin = NULL;
  1422 		iCurrentPlugin = NULL;
  1410 		if (PostInterceptEnabled())
  1423 		if (PostInterceptEnabled())
  1411 			{
  1424 			{
  1412 			FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1425 		    FsPluginManager::ReadLockChain();
  1413 			if(iCurrentPlugin && !iCurrentPlugin->IsPluginThread(*this))
  1426 			FsPluginManager::PrevPlugin(iCurrentPlugin, this);
       
  1427 			if(iCurrentPlugin && !iCurrentPlugin->OriginatedFromPlugin(*this))
  1414 				{
  1428 				{
  1415 				SetPostOperation(ETrue);
  1429 				SetPostOperation(ETrue);
  1416 				Dispatch();
  1430 				Dispatch();
       
  1431 				FsPluginManager::UnlockChain();
  1417 				return r;	// EReqActionComplete
  1432 				return r;	// EReqActionComplete
  1418 				}
  1433 				}
       
  1434 			FsPluginManager::UnlockChain();
  1419 			}		
  1435 			}		
  1420 
  1436 
  1421 		Complete(KErrNone);
  1437 		Complete(KErrNone);
  1422 		}
  1438 		}
  1423 	else if (r == EReqActionBusy)	// request postponed ?
  1439 	else if (r == EReqActionBusy)	// request postponed ?
  1441 void CFsMessageRequest::Dispatch(TBool aInitialise, TBool aLowPriority, TBool aDispatchToFront)
  1457 void CFsMessageRequest::Dispatch(TBool aInitialise, TBool aLowPriority, TBool aDispatchToFront)
  1442 	{
  1458 	{
  1443 	__THRD_PRINT1(_L("CFsMessageRequest::Dispatch() req %08x"), this);
  1459 	__THRD_PRINT1(_L("CFsMessageRequest::Dispatch() req %08x"), this);
  1444 
  1460 
  1445 	TInt r = KErrNone;
  1461 	TInt r = KErrNone;
       
  1462 	TBool pluginChainLocked = EFalse;
  1446 
  1463 
  1447 	if (iReqState == EReqStateInitialise && aInitialise)
  1464 	if (iReqState == EReqStateInitialise && aInitialise)
  1448 		{
  1465 		{
  1449 		r = DoInitialise();
  1466 		r = DoInitialise();
  1450 		if (r == EReqActionComplete)
  1467 		if (r == EReqActionComplete)
  1460 			SetState(EReqStateInitialise);	// reinitialize when request is next processed
  1477 			SetState(EReqStateInitialise);	// reinitialize when request is next processed
  1461 			return;
  1478 			return;
  1462 			}
  1479 			}
  1463 		if(!IsPluginSpecific() && (iOwnerPlugin == NULL))
  1480 		if(!IsPluginSpecific() && (iOwnerPlugin == NULL))
  1464 			{
  1481 			{
       
  1482 		    FsPluginManager::ReadLockChain(); // Unlocked in DispatchToPlugin
       
  1483 		    pluginChainLocked = ETrue;
  1465 			iCurrentPlugin = NULL;
  1484 			iCurrentPlugin = NULL;
  1466 			iClientThreadId = 0;
  1485 			iClientThreadId = 0;
  1467 			FsPluginManager::NextPlugin(iCurrentPlugin, this, (TBool)ETrue);
  1486 			FsPluginManager::NextPlugin(iCurrentPlugin, this);
  1468 
  1487 
  1469 			// find out whether there is a plugin registered to post intercept this message
  1488 			// find out whether there is a plugin registered to post intercept this message
  1470 			CFsPlugin* postInterceptPlugin = NULL;
  1489 			CFsPlugin* postInterceptPlugin = NULL;
  1471 			if (iCurrentPlugin == NULL)
  1490 			if (iCurrentPlugin == NULL)
  1472 				FsPluginManager::PrevPlugin(postInterceptPlugin, this, (TBool)ETrue);
  1491 				FsPluginManager::PrevPlugin(postInterceptPlugin, this);
  1473 
  1492 
  1474 			// Save the client's thread Id for subsequent testing by CFsPlugin::IsPluginThread() - doing so on the fly 
  1493 			// Save the client's thread Id for subsequent testing by CFsPlugin::OriginatedFromPlugin() - doing so on the fly 
  1475 			// is risky because some messages are completed early in which case Message().Client() will result in a panic
  1494 			// is risky because some messages are completed early in which case Message().Client() will result in a panic
  1476 			if ((iCurrentPlugin || postInterceptPlugin) && Message().Handle() != NULL && Message().Handle() != KLocalMessageHandle)
  1495 			if ((iCurrentPlugin || postInterceptPlugin) && Message().Handle() != NULL && Message().Handle() != KLocalMessageHandle)
  1477 				{
  1496 				{
  1478 				RThread thread;
  1497 				RThread thread;
  1479 				Message().Client(thread, EOwnerThread);
  1498 				Message().Client(thread, EOwnerThread);
  1488 	if (iReqState > EReqStateInitialise && DispatchToPlugin())
  1507 	if (iReqState > EReqStateInitialise && DispatchToPlugin())
  1489 		{
  1508 		{
  1490 		__PLUGIN_PRINT1(_L("PLUGIN: CFsMessageRequest %x dispatched to plugin (async)"), this);
  1509 		__PLUGIN_PRINT1(_L("PLUGIN: CFsMessageRequest %x dispatched to plugin (async)"), this);
  1491 		// The request has been delivered to the plugin thread
  1510 		// The request has been delivered to the plugin thread
  1492 		//  - leave the main thread now and await asynchronous completion
  1511 		//  - leave the main thread now and await asynchronous completion
       
  1512 		if(pluginChainLocked)
       
  1513 		    FsPluginManager::UnlockChain();
  1493 		return;
  1514 		return;
  1494 		}
  1515 		}
  1495 
  1516 
       
  1517 	//DispatchToPlugin didn't (deliver then unlock) so make sure we unlock here.
       
  1518     if(pluginChainLocked)
       
  1519         FsPluginManager::UnlockChain();
  1496 
  1520 
  1497 	// Is there a PostInitialise function ?
  1521 	// Is there a PostInitialise function ?
  1498 	if (iReqState ==  EReqStatePostInitialise && aInitialise && r == KErrNone)
  1522 	if (iReqState ==  EReqStatePostInitialise && aInitialise && r == KErrNone)
  1499 		{
  1523 		{
  1500 		TInt r = PostInitialise();
  1524 		TInt r = PostInitialise();
  1501 		if (r == EReqActionComplete)
  1525 		if (r == EReqActionComplete)
       
  1526 		    {
  1502 			return;
  1527 			return;
       
  1528 		    }
  1503 		else if (r == EReqActionBusy)				// request postponed ?
  1529 		else if (r == EReqActionBusy)				// request postponed ?
  1504 			SetState(EReqStatePostInitialise);		// reinitialize when request is next processed
  1530 			SetState(EReqStatePostInitialise);		// reinitialize when request is next processed
  1505 		}
  1531 		}
  1506 
  1532 
  1507 
  1533 
  1557 
  1583 
  1558 TBool CFsMessageRequest::DispatchToPlugin()
  1584 TBool CFsMessageRequest::DispatchToPlugin()
  1559 //
  1585 //
  1560 // Common route: Receive -> Process -> Dispatch -> DispatchToPlugin
  1586 // Common route: Receive -> Process -> Dispatch -> DispatchToPlugin
  1561 //
  1587 //
       
  1588 // (Is called with FsPluginManager ReadLocked)
  1562 	{
  1589 	{
  1563 	TInt drivenumber = DriveNumber();
  1590 	TInt drivenumber = DriveNumber();
  1564 	if(iCurrentPlugin)
  1591 	if(iCurrentPlugin)
  1565 		{		
  1592 		{		
  1566 		FOREVER
  1593 		FOREVER
  1570 				{
  1597 				{
  1571 				// No more plug-ins need to process this request
  1598 				// No more plug-ins need to process this request
  1572 				iCurrentPlugin = NULL;
  1599 				iCurrentPlugin = NULL;
  1573 				}
  1600 				}
  1574 
  1601 
  1575 			while(iCurrentPlugin && iCurrentPlugin->IsPluginThread(*this))
  1602 			while(iCurrentPlugin && iCurrentPlugin->OriginatedFromPlugin(*this))
  1576 				{
  1603 				{
  1577 				// Skip the current plugin if the request originated from the plugin
  1604 				// Skip the current plugin if the request originated from the plugin
  1578 				if(IsPostOperation())
  1605 				if(IsPostOperation())
  1579 					{
  1606 					{
  1580 					FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1607 					FsPluginManager::PrevPlugin(iCurrentPlugin, this);
  1581 					}
  1608 					}
  1582 				else
  1609 				else
  1583 					{
  1610 					{
  1584 					FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1611 					FsPluginManager::NextPlugin(iCurrentPlugin, this);
  1585 					}
  1612 					}
  1586 				}
  1613 				}
  1587 				
  1614 				
  1588 			if(iCurrentPlugin)
  1615 			if(iCurrentPlugin)
  1589 				{
  1616 				{
  1609 					{
  1636 					{
  1610 					// The plugin has processed synchronously (case 1)
  1637 					// The plugin has processed synchronously (case 1)
  1611 					//  - Pass the message on to the next plugin
  1638 					//  - Pass the message on to the next plugin
  1612 					if(FsFunction() != EFsPluginOpen)
  1639 					if(FsFunction() != EFsPluginOpen)
  1613 					    {
  1640 					    {
  1614 	                    FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1641 	                    FsPluginManager::NextPlugin(iCurrentPlugin, this);
  1615 	                    continue;
  1642 	                    continue;
  1616 					    }
  1643 					    }
  1617 					else // FsFunction == EFsPluginOpen
  1644 					else // FsFunction == EFsPluginOpen
  1618 					    {
  1645 					    {
  1619 					    /* 
  1646 					    /* 
  1620 					     * PluginOpen requests should not be passed down the plugin stack.
  1647 					     * PluginOpen requests should not be passed down the plugin stack.
  1621 					     * 
  1648 					     * 
  1622 
       
  1623 					     */
  1649 					     */
  1624 					    iCurrentPlugin = NULL;
  1650 					    iCurrentPlugin = NULL;
  1625 					    continue;
  1651 					    continue;
  1626 					    }
  1652 					    }
  1627 					}
  1653 					}
  1628 				else if(err == KPluginMessageComplete)
  1654 				else if(err == KPluginMessageComplete)
  1629 					{
  1655 					{
  1630 					// The plugin has processed synchronously (case 2)
  1656 					// The plugin has processed synchronously (case 2)
  1631 					//  - Pass the message back up the stack
  1657 					//  - Pass the message back up the stack
  1632 					SetPostOperation(ETrue);
  1658 					SetPostOperation(ETrue);
  1633 					FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
  1659 					FsPluginManager::PrevPlugin(iCurrentPlugin, this);
  1634 					continue;
  1660 					continue;
  1635 					}
  1661 					}
  1636 				_LIT(KPanic,"Panic: F32-BAD-PLUGIN-ERROR");
  1662 				_LIT(KPanic,"Panic: F32-BAD-PLUGIN-ERROR");
  1637 				Panic(KPanic, err);
  1663 				Panic(KPanic, err);
  1638 				}
  1664 				}
  1650 				return EFalse;
  1676 				return EFalse;
  1651 				}
  1677 				}
  1652 			}			
  1678 			}			
  1653 		}
  1679 		}
  1654 
  1680 
       
  1681 	/*
       
  1682 	 * Special case- DismountPlugin runs in the context of the plugin thread
       
  1683 	 */
  1655 	if(iOperation->Function() == EFsDismountPlugin)
  1684 	if(iOperation->Function() == EFsDismountPlugin)
  1656 		{
  1685 		{
  1657 		// Don't pass plugin dismounts to the drive thread
  1686 		// Don't pass plugin dismounts to the drive thread
       
  1687 	    FsPluginManager::UnlockChain();
  1658 		Process();
  1688 		Process();
       
  1689 		FsPluginManager::ReadLockChain(); //inverted unlock/lock to get around dismount plugin being a special case
  1659 		return(ETrue);
  1690 		return(ETrue);
  1660 		}
  1691 		}
  1661 		
       
  1662 	return EFalse;
  1692 	return EFalse;
  1663 	}
  1693 	}
  1664 
  1694 
  1665 TDrive* CFsMessageRequest::Drive()
  1695 TDrive* CFsMessageRequest::Drive()
  1666 //
  1696 //