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