@@ -406,6 +406,25 @@ static inline zend_bool pthreads_store_update_shared_property(pthreads_object_t*
406
406
return result ;
407
407
}
408
408
409
+ /* {{{ */
410
+ int pthreads_store_read_local_property (zend_object * object , zend_string * key , int type , zval * read ) {
411
+ zval * property ;
412
+ pthreads_zend_object_t * threaded = PTHREADS_FETCH_FROM (object );
413
+
414
+ if (threaded -> std .properties ) {
415
+ property = zend_hash_find (threaded -> std .properties , key );
416
+
417
+ if (property && pthreads_store_valid_local_cache_item (property )) {
418
+ pthreads_monitor_unlock (& threaded -> ts_obj -> monitor );
419
+ ZVAL_DEINDIRECT (property );
420
+ ZVAL_COPY (read , property );
421
+ return SUCCESS ;
422
+ }
423
+ }
424
+
425
+ return FAILURE ;
426
+ } /* }}} */
427
+
409
428
/* {{{ */
410
429
int pthreads_store_read (zend_object * object , zval * key , int type , zval * read ) {
411
430
int result = FAILURE ;
@@ -492,8 +511,8 @@ static zend_string* pthreads_store_restore_string(zend_string* string) {
492
511
}
493
512
494
513
/* {{{ */
495
- int pthreads_store_write (zend_object * object , zval * key , zval * write , zend_bool coerce_array_to_threaded ) {
496
- int result = FAILURE ;
514
+ pthreads_store_write_result pthreads_store_write_ex (zend_object * object , zval * key , zval * write , zend_bool coerce_array_to_threaded , zend_bool overwrite ) {
515
+ pthreads_store_write_result result = WRITE_FAIL_UNKNOWN ;
497
516
zval vol , member , zstorage ;
498
517
pthreads_zend_object_t * threaded =
499
518
PTHREADS_FETCH_FROM (object );
@@ -511,7 +530,7 @@ int pthreads_store_write(zend_object *object, zval *key, zval *write, zend_bool
511
530
}
512
531
513
532
if (pthreads_store_save_zval (& threaded -> owner , & zstorage , write ) != SUCCESS ) {
514
- return FAILURE ;
533
+ return WRITE_FAIL_NOT_THREAD_SAFE ;
515
534
}
516
535
517
536
if (pthreads_monitor_lock (& ts_obj -> monitor )) {
@@ -523,10 +542,26 @@ int pthreads_store_write(zend_object *object, zval *key, zval *write, zend_bool
523
542
coerced = pthreads_store_coerce (key , & member );
524
543
}
525
544
526
- zend_bool was_pthreads_object = pthreads_store_member_is_cacheable (object , & member );
527
- result = pthreads_store_update_shared_property (ts_obj , & member , & zstorage );
528
- if (result == SUCCESS && was_pthreads_object ) {
529
- _pthreads_store_bump_modcount_nolock (threaded );
545
+ zend_bool ok = true;
546
+ if (!overwrite ) {
547
+ if (Z_TYPE (member ) == IS_LONG ) {
548
+ ok = !zend_hash_index_exists (& ts_obj -> props .hash , Z_LVAL (member ));
549
+ } else {
550
+ ok = !zend_hash_exists (& ts_obj -> props .hash , Z_STR (member ));
551
+ }
552
+ if (!ok ) {
553
+ result = WRITE_FAIL_WOULD_OVERWRITE ;
554
+ }
555
+ }
556
+
557
+ if (ok ) {
558
+ zend_bool was_pthreads_object = pthreads_store_member_is_cacheable (object , & member );
559
+ if (pthreads_store_update_shared_property (ts_obj , & member , & zstorage ) == SUCCESS ) {
560
+ result = WRITE_SUCCESS ;
561
+ if (was_pthreads_object ) {
562
+ _pthreads_store_bump_modcount_nolock (threaded );
563
+ }
564
+ }
530
565
}
531
566
//this isn't necessary for any specific property write, but since we don't have any other way to clean up local
532
567
//cached Threaded references that are dead, we have to take the opportunity
@@ -535,7 +570,7 @@ int pthreads_store_write(zend_object *object, zval *key, zval *write, zend_bool
535
570
pthreads_monitor_unlock (& ts_obj -> monitor );
536
571
}
537
572
538
- if (result != SUCCESS ) {
573
+ if (result != WRITE_SUCCESS ) {
539
574
pthreads_store_storage_dtor (& zstorage );
540
575
} else {
541
576
pthreads_store_update_local_property (& threaded -> std , & member , write );
@@ -547,6 +582,10 @@ int pthreads_store_write(zend_object *object, zval *key, zval *write, zend_bool
547
582
return result ;
548
583
} /* }}} */
549
584
585
+ int pthreads_store_write (zend_object * object , zval * key , zval * write , zend_bool coerce_array_to_threaded ) {
586
+ return pthreads_store_write_ex (object , key , write , coerce_array_to_threaded , true) == WRITE_SUCCESS ? SUCCESS : FAILURE ;
587
+ }
588
+
550
589
/* {{{ */
551
590
int pthreads_store_count (zend_object * object , zend_long * count ) {
552
591
pthreads_object_t * ts_obj = PTHREADS_FETCH_TS_FROM (object );
0 commit comments