View | Details | Raw Unified | Return to issue 61771
Collapse All | Expand All

(-)inc/svdobj.hxx (-8 / +5 lines)
Lines 141-146 Link Here
141
class SfxPoolItem;
141
class SfxPoolItem;
142
class SdrLineGeometry;
142
class SdrLineGeometry;
143
class SdrVirtObj;
143
class SdrVirtObj;
144
class SvxShape;
144
145
145
namespace sdr
146
namespace sdr
146
{
147
{
Lines 669-676 Link Here
669
	// ueberladen, wenn man sich von SdrObjPlusData abgeleitet hat:
670
	// ueberladen, wenn man sich von SdrObjPlusData abgeleitet hat:
670
	virtual SdrObjPlusData* NewPlusData() const;
671
	virtual SdrObjPlusData* NewPlusData() const;
671
672
672
	// this is a weak reference to a possible living api wrapper for this shape
673
	// this is a direct pointer to a possible living api wrapper for this shape
673
	::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface > mxUnoShape;
674
    SvxShape* mpUnoShape;
674
675
675
protected:
676
protected:
676
	// Diese 3 Methoden muss ein abgeleitetes Objekt ueberladen, wenn es eigene
677
	// Diese 3 Methoden muss ein abgeleitetes Objekt ueberladen, wenn es eigene
Lines 1295-1301 Link Here
1295
	////////////////////////////////////////////////////////////////////////////////////////////////////
1296
	////////////////////////////////////////////////////////////////////////////////////////////////////
1296
	// access to the UNO representation of the shape
1297
	// access to the UNO representation of the shape
1297
	::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getUnoShape();
1298
	::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getUnoShape();
1298
	::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface > getWeakUnoShape() { return mxUnoShape; }
1299
1299
1300
	// helper struct for granting access exclusive to SvxShape
1300
	// helper struct for granting access exclusive to SvxShape
1301
	struct GrantXShapeAccess
1301
	struct GrantXShapeAccess
Lines 1306-1317 Link Here
1306
	};
1306
	};
1307
1307
1308
	// setting the UNO representation is allowed for the UNO representation itself only!
1308
	// setting the UNO representation is allowed for the UNO representation itself only!
1309
	void setUnoShape(
1309
	void setUnoShape( SvxShape* _pUnoShape, GrantXShapeAccess aGrant )
1310
		const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxUnoShape,
1311
		GrantXShapeAccess aGrant
1312
	)
1313
	{
1310
	{
1314
		mxUnoShape = _rxUnoShape;
1311
		mpUnoShape = _pUnoShape;
1315
	}
1312
	}
1316
1313
1317
	////////////////////////////////////////////////////////////////////////////////////////////////////
1314
	////////////////////////////////////////////////////////////////////////////////////////////////////
(-)inc/unoshape.hxx (+11 lines)
Lines 229-234 Link Here
229
	void SetTemporaryShape( sal_Bool bTemporary );
229
	void SetTemporaryShape( sal_Bool bTemporary );
230
	void ChangeModel( SdrModel* pNewModel );
230
	void ChangeModel( SdrModel* pNewModel );
231
231
232
    // helper struct for granting exclusive access to selected methods to SdrObject only
233
    struct GrantSdrObjectAccess { friend class SdrObject; private: GrantSdrObjectAccess() { } };
234
    /** is called when the SdrObject we represent is going to die
235
        @precond
236
            The SolarMutex must be locked when calling this method
237
      */
238
    void   onSdrObjectDying( GrantSdrObjectAccess );
239
232
	void InvalidateSdrObject() { pObj = NULL; };
240
	void InvalidateSdrObject() { pObj = NULL; };
233
	SvxItemPropertySet& GetPropertySet() { return aPropSet; }
241
	SvxItemPropertySet& GetPropertySet() { return aPropSet; }
234
	SdrObject* GetSdrObject() const {return pObj;}
242
	SdrObject* GetSdrObject() const {return pObj;}
Lines 264-269 Link Here
264
272
265
	// SfxListener
273
	// SfxListener
266
	virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw ();
274
	virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw ();
275
276
    // XInterface
277
	virtual void SAL_CALL release() throw();
267
278
268
    // XNamed
279
    // XNamed
269
    virtual ::rtl::OUString SAL_CALL getName(  ) throw(::com::sun::star::uno::RuntimeException);
280
    virtual ::rtl::OUString SAL_CALL getName(  ) throw(::com::sun::star::uno::RuntimeException);
(-)source/svdraw/svdobj.cxx (-37 / +42 lines)
Lines 495-503 Link Here
495
	nLayerId(0),
495
	nLayerId(0),
496
	mpProperties(0L),
496
	mpProperties(0L),
497
	// #110094#
497
	// #110094#
498
	mpViewContact(0L)
498
	mpViewContact(0L),
499
    mpUnoShape( NULL )
499
{
500
{
500
	DBG_CTOR(SdrObject,NULL);
501
    DBG_CTOR(SdrObject,NULL);
501
	bVirtObj         =FALSE;
502
	bVirtObj         =FALSE;
502
	bBoundRectDirty  =TRUE;
503
	bBoundRectDirty  =TRUE;
503
	bSnapRectDirty   =TRUE;
504
	bSnapRectDirty   =TRUE;
Lines 531-536 Link Here
531
532
532
SdrObject::~SdrObject()
533
SdrObject::~SdrObject()
533
{
534
{
535
    DBG_TESTSOLARMUTEX();
536
534
	// tell all the registered ObjectUsers that the page is in destruction
537
	// tell all the registered ObjectUsers that the page is in destruction
535
	for(::sdr::ObjectUserVector::iterator aIterator = maObjectUsers.begin(); aIterator != maObjectUsers.end(); aIterator++)
538
	for(::sdr::ObjectUserVector::iterator aIterator = maObjectUsers.begin(); aIterator != maObjectUsers.end(); aIterator++)
536
	{
539
	{
Lines 543-551 Link Here
543
	// when they get called from ObjectInDestruction().
546
	// when they get called from ObjectInDestruction().
544
	maObjectUsers.clear();
547
	maObjectUsers.clear();
545
548
546
	uno::Reference< lang::XComponent > xShape( mxUnoShape, uno::UNO_QUERY );
549
    if ( mpUnoShape )
547
	if( xShape.is() )
550
    {
548
		xShape->dispose();
551
        mpUnoShape->onSdrObjectDying( SvxShape::GrantSdrObjectAccess() );
552
        mpUnoShape = NULL;
553
    }
549
554
550
	DBG_DTOR(SdrObject,NULL);
555
	DBG_DTOR(SdrObject,NULL);
551
	SendUserCall(SDRUSERCALL_DELETE, GetLastBoundRect());
556
	SendUserCall(SDRUSERCALL_DELETE, GetLastBoundRect());
Lines 595-607 Link Here
595
	// update listeners at possible api wrapper object
600
	// update listeners at possible api wrapper object
596
	if( pModel != pNewModel )
601
	if( pModel != pNewModel )
597
	{
602
	{
598
		uno::Reference< uno::XInterface > xShape( mxUnoShape );
603
        DBG_TESTSOLARMUTEX();
599
		if( xShape.is() )
604
        if ( mpUnoShape )
600
		{
605
			mpUnoShape->ChangeModel( pNewModel );
601
			SvxShape* pShape = SvxShape::getImplementation( xShape );
602
			if( pShape )
603
				pShape->ChangeModel( pNewModel );
604
		}
605
	}
606
	}
606
607
607
	pModel = pNewModel;
608
	pModel = pNewModel;
Lines 3770-3800 Link Here
3770
3771
3771
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SdrObject::getUnoShape()
3772
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SdrObject::getUnoShape()
3772
{
3773
{
3773
	// try weak reference first
3774
    DBG_TESTSOLARMUTEX();
3774
	uno::Reference< uno::XInterface > xShape( mxUnoShape );
3775
3775
	if( !xShape.is() )
3776
    uno::Reference< uno::XInterface > xShape;
3776
	{
3777
3777
		if ( pPage )
3778
    // try weak reference first
3778
		{
3779
    if ( mpUnoShape )
3779
			uno::Reference< uno::XInterface > xPage( pPage->getUnoPage() );
3780
        xShape = xShape.query( *mpUnoShape );
3780
			if( xPage.is() )
3781
    else
3781
			{
3782
    {
3782
				SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation(xPage);
3783
        if ( pPage )
3783
				if( pDrawPage )
3784
	    {
3784
				{
3785
		    uno::Reference< uno::XInterface > xPage( pPage->getUnoPage() );
3785
					// create one
3786
		    if( xPage.is() )
3786
					xShape = pDrawPage->_CreateShape( this );
3787
		    {
3787
					mxUnoShape = xShape;
3788
			    SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation(xPage);
3788
				}
3789
			    if( pDrawPage )
3789
			}
3790
				    // create one
3790
		}
3791
				    xShape = pDrawPage->_CreateShape( this );
3791
		else
3792
		    }
3792
		{
3793
	    }
3793
			uno::Reference< drawing::XShape > xS( SvxDrawPage::CreateShapeByTypeAndInventor( GetObjIdentifier(), GetObjInventor(), this, NULL ) );
3794
	    else
3794
			xShape = xS;
3795
	    {
3795
			mxUnoShape = xShape;
3796
		    uno::Reference< drawing::XShape > xS( SvxDrawPage::CreateShapeByTypeAndInventor( GetObjIdentifier(), GetObjInventor(), this, NULL ) );
3796
		}
3797
		    xShape = xS;
3797
	}
3798
	    }
3799
        mpUnoShape = SvxShape::getImplementation( xShape );
3800
        DBG_ASSERT( ( mpUnoShape != NULL ) || ( !xShape.is() ),
3801
            "SdrObject::getUnoShape: invalid SvxShape!" );
3802
    }
3798
3803
3799
	return xShape;
3804
	return xShape;
3800
}
3805
}
(-)source/unodraw/unoshape.cxx (-23 / +90 lines)
Lines 330-335 Link Here
330
	if( pModel )
330
	if( pModel )
331
		EndListening( *pModel );
331
		EndListening( *pModel );
332
332
333
    if ( pObj )
334
    {
335
	    pObj->setUnoShape( NULL, SdrObject::GrantXShapeAccess() );
336
        pObj = NULL;
337
    }
338
333
	if( mpImpl )
339
	if( mpImpl )
334
	{
340
	{
335
		if(mpImpl->mpMaster)
341
		if(mpImpl->mpMaster)
Lines 436-441 Link Here
436
}
442
}
437
443
438
//----------------------------------------------------------------------
444
//----------------------------------------------------------------------
445
void SvxShape::onSdrObjectDying( GrantSdrObjectAccess )
446
{
447
    DBG_TESTSOLARMUTEX();
448
449
    if ( m_refCount == 0 )
450
    {
451
        // we're currently dying, anyway. No dispose notifications, just reset the pObj
452
        // member so we don't access it in our dtor anymore.
453
        pObj = 0;
454
    }
455
    else
456
    {
457
        dispose();
458
    }
459
}
460
461
//----------------------------------------------------------------------
439
SvxShape* SvxShape::GetShapeForSdrObj( SdrObject* pObj ) throw()
462
SvxShape* SvxShape::GetShapeForSdrObj( SdrObject* pObj ) throw()
440
{
463
{
441
	return getImplementation( pObj->getUnoShape() );
464
	return getImplementation( pObj->getUnoShape() );
Lines 443-449 Link Here
443
466
444
void SvxShape::Init() throw()
467
void SvxShape::Init() throw()
445
{
468
{
446
	if( NULL == mpImpl )
469
    DBG_TESTSOLARMUTEX();
470
471
    if( NULL == mpImpl )
447
	{
472
	{
448
		mpImpl = new SvxShapeImpl;
473
		mpImpl = new SvxShapeImpl;
449
		mpImpl->mpItemSet = NULL;
474
		mpImpl->mpItemSet = NULL;
Lines 463-473 Link Here
463
	if(pObj == NULL)
488
	if(pObj == NULL)
464
		return;
489
		return;
465
490
466
	osl_incrementInterlockedCount( &m_refCount );
491
	pObj->setUnoShape( this, SdrObject::GrantXShapeAccess() );
467
	{
468
		pObj->setUnoShape( *this, SdrObject::GrantXShapeAccess() );
469
	}
470
	osl_decrementInterlockedCount( &m_refCount );
471
492
472
	pModel = pObj->GetModel();
493
	pModel = pObj->GetModel();
473
494
Lines 529-534 Link Here
529
			EndListening( *pObj->GetModel() );
550
			EndListening( *pObj->GetModel() );
530
		}
551
		}
531
552
553
        if ( pObj )
554
            pObj->setUnoShape( NULL, SdrObject::GrantXShapeAccess() );
532
		pObj = pNewObj;
555
		pObj = pNewObj;
533
556
534
		Init();
557
		Init();
Lines 1074-1082 Link Here
1074
		(pSdrHint->GetKind() != HINT_OBJCHG)))
1097
		(pSdrHint->GetKind() != HINT_OBJCHG)))
1075
        return;
1098
        return;
1076
1099
1077
	uno::Reference< uno::XInterface > xSelf( pObj->getWeakUnoShape() );
1100
    DBG_TESTSOLARMUTEX();
1101
1102
    if ( m_refCount == 0 )
1103
    {
1104
        // we're probably just blocking inside our |release| call, in another thread.
1105
        // Don't create the temporary reference below, this would cause a duplicate
1106
        // "delete this"
1107
        return;
1108
    }
1109
1110
    uno::Reference< uno::XInterface > xSelf( pObj->getUnoShape() );
1078
	if( !xSelf.is() )
1111
	if( !xSelf.is() )
1079
	{
1112
	{
1113
        if ( pObj )
1114
	        pObj->setUnoShape( NULL, SdrObject::GrantXShapeAccess() );
1080
		pObj = NULL;
1115
		pObj = NULL;
1081
		return;
1116
		return;
1082
	}
1117
	}
Lines 1123-1128 Link Here
1123
1158
1124
	if( bClearMe )
1159
	if( bClearMe )
1125
	{
1160
	{
1161
        if ( pObj )
1162
	        pObj->setUnoShape( NULL, SdrObject::GrantXShapeAccess() );
1126
		pObj = NULL;
1163
		pObj = NULL;
1127
		if(!bDisposing)
1164
		if(!bDisposing)
1128
			dispose();
1165
			dispose();
Lines 1292-1297 Link Here
1292
1329
1293
//----------------------------------------------------------------------
1330
//----------------------------------------------------------------------
1294
1331
1332
void SAL_CALL SvxShape::release() throw()
1333
{
1334
	Reference<XInterface > xDelegator( xDelegator );
1335
	if ( xDelegator.is() )
1336
		xDelegator->release();
1337
	else
1338
    {
1339
        if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
1340
        {
1341
            // make releasing the last reference, plus subsequent deletion of |this|,
1342
            // a solar-guarded transaction. Else, we might run into different race conditions
1343
            // if one thread releases a reference to an SvxShape, and another thread destroys
1344
            // the respective SdrObject, resulting in either one (SvxShape/SdrObject) accessing
1345
            // a dead counterpart (SdtObject/SvxShape), or an SvxShape being deleted twice du
1346
            // to temporary references created in thread A while thread B blocks within the
1347
            // dtor-chain of an SvxShape derivee.
1348
	        OGuard aGuard( Application::GetSolarMutex() );
1349
            osl_incrementInterlockedCount( &m_refCount );
1350
		    SvxShape_UnoImplHelper::release();
1351
        }
1352
    }
1353
}
1354
1355
//----------------------------------------------------------------------
1356
1295
// XNamed
1357
// XNamed
1296
OUString SAL_CALL SvxShape::getName(  ) throw(::com::sun::star::uno::RuntimeException)
1358
OUString SAL_CALL SvxShape::getName(  ) throw(::com::sun::star::uno::RuntimeException)
1297
{
1359
{
Lines 1351-1357 Link Here
1351
	OGuard aGuard( Application::GetSolarMutex() );
1413
	OGuard aGuard( Application::GetSolarMutex() );
1352
1414
1353
	if( bDisposing )
1415
	if( bDisposing )
1354
		return;	// catched a recursion
1416
		return;	// caught a recursion
1355
1417
1356
	bDisposing = sal_True;
1418
	bDisposing = sal_True;
1357
1419
Lines 1360-1380 Link Here
1360
	aDisposeListeners.disposeAndClear(aEvt);
1422
	aDisposeListeners.disposeAndClear(aEvt);
1361
1423
1362
	SdrObject* pObj = GetSdrObject();
1424
	SdrObject* pObj = GetSdrObject();
1363
	if(pObj && pObj->IsInserted() && pObj->GetPage() )
1425
    if ( pObj )
1364
	{
1426
    {
1365
		SdrPage* pPage = pObj->GetPage();
1427
	    pObj->setUnoShape( NULL, SdrObject::GrantXShapeAccess() );
1366
		// SdrObject aus der Page loeschen
1428
	    if ( pObj->IsInserted() && pObj->GetPage() )
1367
		sal_uInt32 nCount = pPage->GetObjCount();
1429
	    {
1368
		for( sal_uInt32 nNum = 0; nNum < nCount; nNum++ )
1430
		    SdrPage* pPage = pObj->GetPage();
1369
		{
1431
		    // SdrObject aus der Page loeschen
1370
			if(pPage->GetObj(nNum) == pObj)
1432
		    sal_uInt32 nCount = pPage->GetObjCount();
1371
			{
1433
		    for( sal_uInt32 nNum = 0; nNum < nCount; nNum++ )
1372
				delete pPage->RemoveObject(nNum);
1434
		    {
1373
				InvalidateSdrObject();
1435
			    if(pPage->GetObj(nNum) == pObj)
1374
				break;
1436
			    {
1375
			}
1437
				    delete pPage->RemoveObject(nNum);
1376
		}
1438
				    InvalidateSdrObject();
1377
	}
1439
				    break;
1440
			    }
1441
		    }
1442
	    }
1443
        this->pObj = NULL;
1444
    }
1378
1445
1379
	if( pModel )
1446
	if( pModel )
1380
	{
1447
	{

Return to issue 61771