Skip to content

Commit

Permalink
Move zend_object handler to the end
Browse files Browse the repository at this point in the history
In php7 the zend_object handler structure is inlined (is no longer a pointer,
but rather variable sized depending on various things, so it needs to be at the
end of the container class.

This is mentioned in the extensive /s upgrading documentation from Zend

See "custom objects":
https://wiki.php.net/phpng-upgrading

In addition I believe that the zend library now takes care of freeing the overall
structure, so that shouldn't be done anymore if running php >= 7.0.0.
  • Loading branch information
michael-grunder committed Nov 23, 2016
1 parent 041478b commit 3410796
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
6 changes: 3 additions & 3 deletions cluster_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,6 @@ typedef struct clusterFoldItem clusterFoldItem;

/* RedisCluster implementation structure */
typedef struct redisCluster {
/* Object reference for Zend */
zend_object std;

/* Timeout and read timeout (for normal operations) */
double timeout;
double read_timeout;
Expand Down Expand Up @@ -244,6 +241,9 @@ typedef struct redisCluster {
int redir_host_len;
unsigned short redir_slot;
unsigned short redir_port;

/* Zend object handler */
zend_object std;
} redisCluster;

/* RedisCluster response processing callback */
Expand Down
18 changes: 12 additions & 6 deletions redis_cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,14 +331,20 @@ create_cluster_context(zend_class_entry *class_type TSRMLS_DC) {
#else
object_properties_init(&cluster->std, class_type);
memcpy(&RedisCluster_handlers, zend_get_std_object_handlers(), sizeof(RedisCluster_handlers));
RedisCluster_handlers.free_obj = free_cluster_context;
RedisCluster_handlers.offset = XtOffsetOf(redisCluster, std);
RedisCluster_handlers.free_obj = free_cluster_context;

cluster->std.handlers = &RedisCluster_handlers;

return &cluster->std;
#endif
}

/* Helper to retrieve the redisCluster object from the zend_object member */

This comment has been minimized.

Copy link
@yatsukhnenko

yatsukhnenko Nov 23, 2016

Member

We don't need this helper because we have GET_CONTEXT macro which does the same work

This comment has been minimized.

Copy link
@michael-grunder

michael-grunder Nov 23, 2016

Author Member

Doesn't that get the struct from a ZVAL though? I'll admit to being a bit rusty. :)

This comment has been minimized.

Copy link
@yatsukhnenko

yatsukhnenko Nov 23, 2016

Member

Yes, you are right. It is for zvals. I'm a bit sleepy :)

static redisCluster *getClusterObject(zend_object *object) {
return (redisCluster*)((char*)(object) - XtOffsetOf(redisCluster, std));
}

/* Free redisCluster context */
void
#if (PHP_MAJOR_VERSION < 7)
Expand All @@ -347,10 +353,7 @@ free_cluster_context(void *object TSRMLS_DC)
free_cluster_context(zend_object *object)
#endif
{
redisCluster *cluster;

// Grab context
cluster = (redisCluster*)object;
redisCluster *cluster = getClusterObject(object);

// Free any allocated prefix, as well as the struct
if(cluster->flags->prefix) efree(cluster->flags->prefix);
Expand All @@ -366,8 +369,11 @@ free_cluster_context(zend_object *object)

if(cluster->err) efree(cluster->err);

// Finally, free the redisCluster structure itself
zend_object_std_dtor(&cluster->std TSRMLS_CC);

#if (PHP_MAJOR_VERSION < 7)
efree(cluster);
#endif
}

/* Attempt to connect to a Redis cluster provided seeds and timeout options */
Expand Down

0 comments on commit 3410796

Please sign in to comment.